在当前页面弹出一个带 Form 表单的 Modal 是一个很常见的场景。
只需要在 Form 表单外面包一个 Modal 就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| class ContactForm extends React.Component { render() { const {getFieldDecorator} = this.props.form; const formItemLayout = { labelCol: {span: 6}, wrapperCol: {span: 18}, };
return ( <Modal width={740} title={this.props.title} visible={this.props.visible} confirmLoading={this.props.confirmLoading} onOk={this.props.handleSave} okText='保存' cancelText='返回' onCancel={this.props.onCancel} > <Form> {getFieldDecorator('id')( <Input type='hidden'/> )} <Row gutter={16}> <Col span={12}> <Form.Item {...formItemLayout} label='姓名'> {getFieldDecorator('name', { rules: [ {required: true, message: '请输入姓名',} ] })( <Input placeholder='请输入'/> )} </Form.Item> </Col> <Col span={12}> <Form.Item {...formItemLayout} label='公司'> {getFieldDecorator('company')( <Input placeholder='请输入'/> )} </Form.Item> </Col> </Row> </Form> </Modal> ); } }
|
1 2 3 4 5 6 7 8
| ContactForm.propTypes = { title: PropTypes.string.isRequired, visible: PropTypes.bool, initValues: PropTypes.object, onCancel: PropTypes.func, handleSave: PropTypes.func, confirmLoading: PropTypes.bool };
|
而 Form 表单的 visible 状态, title 等都由 props 从父组件得到, onOk, onCancel 一般也会提到父组件去处理, 表单只是一个展示组件,业务逻辑都放到外面的 container 组件去处理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| constructor(props) { super(props); this.state = { visible: false, initValues: null, modalTitle: '', }; }
cancelModal = () => { this.setState({ visible: false, }); };
openModal = () => { this.setState({ visible: true, }); };
|
父组件中用 state visible 来控制 Modal 打开与关闭
那么在父组件中怎么拿到 form 呢??? 对用 ref 就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| saveFormRef = (form) => { this.form = form; };
handleSave = () => { const form = this.form; form.validateFields((err, values) => { if (err) { return; }
}); };
<ContactForm ref={this.saveFormRef} title={this.state.modalTitle} visible={this.state.visible} initValues={this.state.initValues} onCancel={this.cancelModal} handleSave={this.handleSave} />
|
这样我们点击 Modal 的保存时就能够处理表单了
一般一个表单除了新建还有编辑状态,编辑状态要给 form fields 赋初值, 那么怎么给 Form 表单赋初值呢??? 一般通过 mapPropsToFields 方法就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const fieldsName = ['id', 'name', 'company'];
const WrappedContactForm = Form.create({
mapPropsToFields (props) { let p = {}; let {initValues} = props; if (initValues) { fieldsName.forEach(key => p[key] = {value: initValues[key]}); } else { fieldsName.forEach(key => p[key] = {value: ''}); } return p; }, })(ContactForm);
export default WrappedContactForm;
|
新建时赋空值,编辑赋初始值, 而初始值通过父组件的 initValues 控制,有时编辑时可能要发异步请求把详情数据取回来再给 initValues 赋值。