前提:
Formily:整体用SchemaForm,其实表体用Form也可以,只是写法有微小区别,思路是一样的。
数据结构:返回的数据结构大约是这样的:
content:[
{
children:{
children:{
...
}
...
}
...
}
{
...}
...
]
实现效果:类似三个Select先选省,再选市,最后选区。在父级选择后,才会加载出子集,且父级发生变化后,子集会作出不同的变化且子集初始选择清空。类似下图
思路和碰壁:
1、数据处理浅谈,主要是用effects生命周期控制,当对应name下的数据发生变化的时候用map对应处理数据。
2、一开始想着使用@formily/antd的Select,后来发现,做出来后当父级发生变化,子集的选定的值不能清空。如果通过effect中的
state.value=null
会有两个不想得到的后果1、组件初始化后如果该字段设置了required:true,那么渲染完成后就会提示没有填入,这不是我们想要的(不管用表单的任何生命周期都是这样)。2、该字段无法选择,一直是空的状态。
3、根据上述思路,如果不定value,用state定义其他属性字段皆不能得到相应的效果。
4、为了改变子集选定的值,尝试过用x-prop、x-component-props传值均不能达到效果,于是目光投到antd,@formily/antd也是从antd在此封装来的,既然封装达不到效果,那么Select组件就需要自己组装了。
计划:
1、用antd的Select自己在此封装出一个能根据数据变化的组件,该组件除了根据传入值做列表渲染之外,当传入数组发生改变的时候清除之前选择的值。在表中复用自己组装的组件。
2、effects仅用于控制数据的拆解和初始化,不负责组件的变化。
3、在第一步中还有个逻辑缺陷,就是如果父级变了,子集没变,依旧不能重新加载。我的处理方法是用effects配合,在该子集的父级上定义变量,如果父级发生变化,会改变变量的值,这个变量同样控制子集是否更新。
条件讲明白了就贴代码解释。
首先贴出封装的Select组件:
import React from 'react'
import {
Select } from 'antd'
import _ from 'lodash'
class CreateSelect extends React.Component {
constructor(props) {
super