项目开发中,我们时常会遇到使用Modal
弹窗和Form
组件搭配实现编辑已有条目和新增条目的功能(如下图),这两个功能所使用到的表单是一样的,唯一的不同点是:编辑条目是要将已有的信息填入表单,而新增条目是表单所有字段为空。
既然表单是一样的,我们当然不想重复代码。刚开始的想法是往Form
组件传入默认值的方式来实现编辑时的填充功能。该方法编辑的时候表单确实是有传入值填充,但是关闭Modal
再点击新增时,发现Form
表单还是有值填充,这不符合我们的要求,查看文档发现了一条信息:
- <Modal /> 和 Form 一起配合使用时,设置 destroyOnClose 也不会在 Modal 关闭时销毁表单字段数据,需要设置 。
这里也不废话了,直接上代码,处理的要点是:通过form.resetFields()
和form.setFieldsValue()
来控制Modal
中的表单数据:
import * as React from 'react'
import { Table, Button, Modal, Form, Row, Col, Input } from 'antd'
import TextArea from 'antd/lib/input/TextArea'
import Column from 'antd/lib/table/Column'
import { OperationType } from 'scripts/consts/enums'
const DomainManage = () => {
const [form] = Form.useForm()
/** 编辑和添加的模态窗 */
const domainModal = (args: {
type: OperationType,
title: string,
initialVal?: any
}) => {
const {
type,
title,
initialVal
} = args
/** 编辑的话填充数据,新增的话直接重置字段 */
if (type === OperationType.edit) {
form.setFieldsValue(initialVal)
} else {
form.resetFields()
}
Modal.confirm({
title: <h3>{title}</h3>,
content: (
<Form form={form} name="domain" >
<Form.Item label="域编码" name="domainCode" >
<Input disabled={type === OperationType.edit} />
</Form.Item>
<Form.Item label="域名称" name="domainName" >
<Input />
</Form.Item>
<Form.Item label="备注" name="remark" >
<TextArea placeholder="请输入备注" />
</Form.Item>
</Form>
),
onOk: () => {
console.log(form.getFieldsValue(['domainCode', 'domainName', 'remark']))
}
})
}
/** 新增条目 */
const handleCreate = () => {
domainModal({
type: OperationType.create,
title: '新建域'
})
}
/** 编辑条目 */
const handleEdit= (row: any) => {
domainModal({
type: OperationType.edit,
title: '编辑域',
initialVal: row
})
}
return (
<>
<Button type="primary" onClick={handleCreate}>新增域</Button>
<Table id="domainList" rowKey="id" >
<Column title="序号" dataIndex="id" />
<Column title="域编码" dataIndex="domainCode" />
<Column title="域名称" dataIndex="domainName" />
<Column title="备注" dataIndex="remark" />
<Column
title="操作"
dataIndex="action"
fixed="right"
render={(_v, row: any) => {
return <Button onClick={handleEdit.bind(this, row)>编辑</Button>
}}
/>
</Table>
</>
)
}
export default DomainManage
注意点:
onOk
函数执行的时候会自动关闭弹窗,当我们表单校验不通过时也会关闭,这不是我们想要的。此时我们可以使用okButtonProps
这个属性结合Modal.confirm()
返回的实例的destroy()
方法来自己控制模态窗的关闭与否。
/** modal 为 Modal.confirm()执行后的实例 */
const modal = Modal.confirm({
...,
content: (...),
okButtonProps: {
onclick: async () => {
await form.validateFields()
//验证通过后的操作
...
/** 处理结束后,调用实例的方法来关闭 Modal */
modal.destroy()
}
}
})
- 若表单中存在
Upload
相关的组件,那在Modal.confirm
中编辑的时候异常蛋疼,建议直接使用Modal
组件的形式。Modal.confirm
中的Form
组件由于渲染的问题会导致删除和添加文件时渲染不同步。