antd Form in modal

2017-11-08  本文已影响3333人  lesliefang

在当前页面弹出一个带 Form 表单的 Modal 是一个很常见的场景。
只需要在 Form 表单外面包一个 Modal 就行了

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>
    );
  }
}

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 组件去处理。

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 就可以了

saveFormRef = (form) => {
  this.form = form;
};

handleSave = () => {
  const form = this.form;
  form.validateFields((err, values) => {
    if (err) {
      return;
    }

    // 这里处理表单  values
  });
};

<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 方法就行了

const fieldsName = ['id', 'name', 'company'];

const WrappedContactForm = Form.create({
 // ****** 这里只处理了字符串类型, 像日期在 antd 中要传 moment 类型
// **** 针对一些特殊字段要做单独处理
  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 赋值。

上一篇 下一篇

猜你喜欢

热点阅读