来源
在react的class组件中与antd3.x的版本,我们要实现表单的双向绑定,只能借助getFieldDecorator来进行绑定,那么如果我们要实现动态添加表单的控件同时进行数据的绑定呢,再同时增加初始化的时候根据接口返回的值初始化一些表单的内容呢,我测! 官网已经有了单项组件的绑定,增加与删除,我们可以根据类似的写法进行设计
第一步
我们需要一个keys数组来记录我们已经有几组组件了,其次需要一个id值来记录我们的表单中每组组件的增加,同时与keys数组结合进行记录
let id = 0;
render() {
// 初始状态就设置为空数组
getFieldDecorator('keys', { initialValue: [] });
// []
const keys = getFieldValue('keys');
}
第二步
绑定我们的组件 我这里将他写为一个变量进行接收,举一个例子; 这里我们的k就发挥作用了,getFieldDecorator会根据[k]的k值来区分添加双向绑定,从而把每次添加的组件的值进行区分,dayType就是你要接收的被绑定的key值
const formItems = keys.map(key => (
<FormItem label="提醒时间" required={false} key={k}>
{getFieldDecorator(`dayType[${k}]`, {
})(
<Select style={{ width: 80 }}>
{dayType.map((config) => (
<Option key={config.value}>
{config.label}
</Option>
))}
</Select>
)}
</FormItem>
))
第三步
进行增加和删除的函数编写
// 增加
add = () => {
const { form } = this.props;
const { id } = this.state;
const keys = form.getFieldValue('keys');
const nextKeys = keys.concat(id ++ );
form.setFieldsValue({
keys: nextKeys,
});
};
// 删除
remove = (k) => {
const { form } = this.props;
const keys = form.getFieldValue('keys');
form.setFieldsValue({
keys: keys.filter((key) => key !== k),
});
};
然后就大功告成啦!
但是,数据初始化要怎么办呢,这里就会让人想到,无非就是初始化的时候将id和keys数组进行赋值,然后再在组件绑定初始值,确实是这样做,看例子
async componentDidMount() {
const result = await ... // 接口获取初始值, 假如这里有2条新数据, 需要初始化两组控件
id = result.length - 1 // 1
this.setState({
resource: result,
});
}
render() {
getFieldDecorator('keys', { initialValue: [...Array(id + 1).keys()] });
const keys = getFieldValue('keys'); // [0, 1]
}
写完之后惊奇的打开网页,我测!!发现并没有按照预期的效果进行渲染,原因是id我们一开始是定义在外面的,并没有定义在state里,导致id变化的时候,react监听不到,所以没有进行重新render,我们只需要把上面的id,在state里面进行控制,然后再判断初始值是否进行添加就可以实现动态添加的功能了
最后
我们可以对表单拿到的数据进行任意的组合,组装成自己想要的数据格式
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
// keys就是多少组数据的数组,可以遍历其来获得每一组组件的值
const { keys, dayType } = values;
const result = keys.map((key) => {
// 举个例子,获取所有的dayType,返回数组对象的数据格式
return {
dayType: dayType[key],
};
});
});
};