antd使用复杂的动态表单时报错

数据的结构是这样的,需要用这个生成一个如下的表单

{
    name: '', // 名称
    groups: [ // 组
 
        {
            groupName: '', // 组名
            state: 1, // 是否启用  1 启用  0 禁用
            isOpen: 1, // 是否展开  1 展开  0 收起
            fields: [ // 字段
 
                {
                    fieldNameCn: '', // 字段中文名
                    tableName: '', // 表名
                    fieldName: '', // 字段在表中的名字
                    state: 1 // 是否启用  1 启用  0 禁用
                            }
            ]
                    }
    ]
}

clipboard.png
点击新增组按钮,给groups增加一条数据,点新增字段给groups[x].fields增加一条数据,删除的话反过来

现在循环出初始的表单,没问题,使用类似下面的方法来注册一个antd的field

{getFieldDecorator(`groups[${index}].groupName`, {})()}

现在点击新增的时候,使用下面的方法设置field会报You cannot set field before registering it.,因为我没有注册groups[1].groupName,因为是新增的,我不可能render遍历的时候就给它注册掉啊

appGroup = () = > {
    const { form } = this.props;
    const groups = form.getFieldValue('groups');
    const group_empty = this.data_form_empty.groups[0];    // 这个不用管,就是个初始的对象
    const key = `groups[${groups.length}]`
    form.setFieldsValue({    // 这里就会报错 You cannot set field before registering it.
        [key]: group_empty
    });
}

也尝试过直接用getFieldDecorator注册一个groups,然后直接setFieldsValue整个groups。但是由于结构比较复杂,所以还会在getFieldDecorator的时候注册类似于groups[${index}].groupName这样的,这样就会报Warning: One field name cannot be part of another, e.g. a and a.b.

阅读 12k
1 个回答

说句你不喜欢听的。我们做过比你这复杂10倍的表单。

出现你描述现象的问题,大多都是解决思路的问题。单击新增的时候,不要想着给页面插数据,而是给数据插数据。
state数据改变的时候,render就会重新渲然。
当你把所有的操作都当作对数据的操作时,你会发现,很多复杂的东西变得很简单。

表单插入最容易出问题的不是你提到的,而是在删除插入表单的时候,录入的数据显示问题。
解决办法就是每次add时,确保一个永远都不会重复的id作为key

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题