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

2024-09-05 22:52

本文主要是介绍【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}><Formform={form}onValuesChange={onValuesChange}layout='vertical'><Form.Itemhiddenname='schemeId'></Form.Item><BasicInfoform={form}data={data}/><ApplyScope form={form} /><WelfareInfoform={form}data={data}/><div className={styles.footer}><ButtonclassName={styles.confirm}onClick={onSubmit}type='primary'style={{ marginRight: 8 }}htmlType='submit'>确定</Button><ButtonclassName={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.Itemname={['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();}})]}><AmountInputNumbermin={0}placeholder={intl.formatMessage({ id: 'LMID_00003499' })}/></Form.Item>)
},
]...
<Form.Item name={'tableKey'}><VVTableborderedcolumns={columns}loading={loading}dataSource={dataSource}// pagination={{ innerPagination: true }}stickyscroll={{ 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 (// 这是一个折叠面板,包含头部和内容区<WelfareCollapseitems={[{key: '1',label: (<AccountTypeform={form}field={field}/>),children: (<WelfareTableform={form}field={field}><Buttontype='default'blockonClick={onRemove}disabled={fields.length <= 1}>删除</Button></WelfareTable>)}]}></WelfareCollapse>);})}<ButtonclassName={styles.addAccountType}type='link'onClick={() => add({ details: [{}] })}><Iconicon='iconsystem_tips_line_3_circle-plus'size={18}/>添加户口类型</Button></>) : null}{!fields.length ? (<div className={styles.empty}><Emptyimage={Empty.NO_RELEASE}description={'暂无信息'}/><Buttontype='primary'onClick={() => add({ details: [{}] })}>添加户口类型</Button></div>) : null}</>)}</Form.List>{contextHolder}</div>);

这篇关于【Antd】Form.List的强大之处,Form.List使用方式细微讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140293

相关文章

Java Stream流与使用操作指南

《JavaStream流与使用操作指南》Stream不是数据结构,而是一种高级的数据处理工具,允许你以声明式的方式处理数据集合,类似于SQL语句操作数据库,本文给大家介绍JavaStream流与使用... 目录一、什么是stream流二、创建stream流1.单列集合创建stream流2.双列集合创建str

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1