【Antd】Form.List的强大之处,Form.List使用方式细微讲解

设想场景

有时候我们会遇到一些复杂的需求,需要用Table嵌套Form.List,逐层嵌套渲染表格表单列表,填写完毕后提交的复杂需求。

由于表单项分布在数据的各个层级里,因此,如何回填表单值就成了一个比较棘手的问题,处理不好,很容易引发一些逻辑bug(例如表单重置后,数据回填、表单校验异常等)

如何处理数据

其实,antd的form实例对象很强,只需要提供给它指定的field和索引i组成的formName(表单项名称)即可自动回填到表单项中,完全不需要人工干预去处理多层级的数据的,如果有需要转换数据结构,也可以先对form实例的指定表单属性进行数据处理,之后再赋值回该属性名即可。

示例:

...

// 初始化设置数据
useEffect(() => {
	// 由于提交的字段格式和回显的字段格式不一致,这边就是进行数据属性的处理
    const newData = reversalFormData(cloneDeep(data));
    // 设置完毕进行重置表单属性值,也就是上面提到的对属性进行转换,也可以自定义对数据处理
    form.setFieldsValue({
        schemeId: newData.schemeId,
        schemeList: newData.schemeList
    });
}, [data, form]);

return
(<div className={styles.formWrap}>
            <Form
                form={form}
                onValuesChange={onValuesChange}
                layout='vertical'
            >
                <Form.Item
                    hidden
                    name='schemeId'
                ></Form.Item>
                <BasicInfo
                    form={form}
                    data={data}
                />
                <ApplyScope form={form} />
                <WelfareInfo
                    form={form}
                    data={data}
                />
                <div className={styles.footer}>
                    <Button
                        className={styles.confirm}
                        onClick={onSubmit}
                        type='primary'
                        style={{ marginRight: 8 }}
                        htmlType='submit'
                    >
                        确定
                    </Button>
                    <Button
                        className={styles.cancel}
                        onClick={onClose}
                    >
                        取消
                    </Button>
                </div>
            </Form>
</div>)

表格+Form的处理方式:子组件的表格处理

const columns = [
{
    title: '基数(MOP)'
    key: 'macaoCardinalityDictValue',
    dataIndex: 'macaoCardinalityDictValue',
    render: (text, record, index) => (
        <SalaryBaseFormItem // 这个是Form.Item表单项的封装组件
            name={['socialSchemeOptionalList', index, 'macaoCardinalityDictValue']}
            label=''
            countryRegionType='MO'
            rules={[{ required: true, message: '请选择'}]}
            selectProps={{
                style: { width: 200 }
            }}
        />
    )
},
{
    title: '基数上限',
    key: 'cardinalityMaximum',
    dataIndex: 'cardinalityMaximum',
    render: (text, record, index) => (
        <Form.Item
            name={['socialSchemeOptionalList', index, 'cardinalityMaximum']}
            rules={[
                { required: true, message: '' },
                ({ getFieldValue }) => ({
                    validator(_, value) {
                    	// 这边包含了对表单项的自定义校验以及赋值的方式
                        const val = getFieldValue(['socialSchemeOptionalList', index, 'cardinalityMinimum']);
                        if (value < val) {
                            form.setFields([
                                {
                                    name: ['socialSchemeOptionalList', index, 'cardinalityMinimum'],
                                    errors: [intl.formatMessage({ id: 'LMID_00038092' })]
                                }
                            ]);
                            return Promise.reject(new Error(intl.formatMessage({ id: 'LMID_00038093' })));
                        }
                        form.setFields([
                            {
                                name: ['socialSchemeOptionalList', index, 'cardinalityMinimum'],
                                errors: undefined
                            }
                        ]);
                        return Promise.resolve();
                    }
                })
            ]}
        >
            <AmountInputNumber
                min={0}
                placeholder={intl.formatMessage({ id: 'LMID_00003499' })}
            />
        </Form.Item>
    )
},
]

...
<Form.Item name={'tableKey'}>
    <VVTable
        bordered
        columns={columns}
        loading={loading}
        dataSource={dataSource}
        // pagination={{ innerPagination: true }}
        sticky
        scroll={{ x: 'max-content' }}
    />
</Form.Item>

Form.List+Form的处理方式:子组件

return (
        <div className={styles.mainlandWelfare}>
            <Form.List name='socialSchemeChinaList'>
                {(fields, { add, remove }) => (
                    <>
                        {fields.length ? (
                            <>
                                {fields.map((field) => {
                                    // 删除户口类型模块
                                    const onRemove = () => {
                                        modal.confirm({
                                            title: '确定删除?',
                                            content: '删除后数据不可恢复,确定删除吗?',
                                            closable: true,
                                            onOk: () => {
                                                form.validateFields([['socialSchemeChinaList', field.name, 'accountTypeMap']], {
                                                    recursive: true
                                                });
                                                remove(field.name);
                                                message.success('删除成功');
                                            }
                                        });
                                    };
                                    return (
                                    	// 这是一个折叠面板,包含头部和内容区
                                        <WelfareCollapse
                                            items={[
                                                {
                                                    key: '1',
                                                    label: (
                                                        <AccountType
                                                            form={form}
                                                            field={field}
                                                        />
                                                    ),
                                                    children: (
                                                        <WelfareTable
                                                            form={form}
                                                            field={field}
                                                        >
                                                            <Button
                                                                type='default'
                                                                block
                                                                onClick={onRemove}
                                                                disabled={fields.length <= 1}
                                                            >
                                                                删除
                                                            </Button>
                                                        </WelfareTable>
                                                    )
                                                }
                                            ]}
                                        ></WelfareCollapse>
                                    );
                                })}
                                <Button
                                    className={styles.addAccountType}
                                    type='link'
                                    onClick={() => add({ details: [{}] })}
                                >
                                    <Icon
                                        icon='iconsystem_tips_line_3_circle-plus'
                                        size={18}
                                    />
                                    添加户口类型
                                </Button>
                            </>
                        ) : null}
                        {!fields.length ? (
                            <div className={styles.empty}>
                                <Empty
                                    image={Empty.NO_RELEASE}
                                    description={'暂无信息'}
                                />
                                <Button
                                    type='primary'
                                    onClick={() => add({ details: [{}] })}
                                >
                                    添加户口类型
                                </Button>
                            </div>
                        ) : null}
                    </>
                )}
            </Form.List>
            {contextHolder}
        </div>
    );

你可能感兴趣的:(list,windows,服务器)