antd頁面多表單校驗

問題

在作antd項目時發現,使用Form.create()(xxx)建立的模塊裏面的Form表單提交前能夠使用this.props.form.validateFieldsAndScroll()判斷是否校驗成功,this.props.form也就是整個頁面模塊的Form,那麼,若是頁面上有多個Form,此時再使用this.props.form.validateFieldsAndScroll()判斷校驗結果就是對整個頁面的Form進行判斷,並不可以對單個Form校驗結果作判斷,問題就在此,如何對單個Form作判斷?javascript

解決方法

  1. 手動校驗,經過對錶單元素添加change事件監聽,獲取表單元素值,手動作校驗,這不失爲一個方法,但有違react設計的思想。
  2. 把表單做爲一個組件獨立出去,頁面經過props傳入表單組件須要的值,在表單組件內部單獨維護相關邏輯,這也是本文推薦的方式。

案例實現

Form子組件:java

import React, { Component } from 'react';
import {Button, Form, Input, Select} from 'antd';

const FormItem = Form.Item;

class Forms extends Component{
  getItemsValue = ()=>{
      const val= this.props.form.getFieldsValue(); // 獲取from表單的值
      return val;
  }
  render(){
    const formItemLayout = {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 8 },
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 },
      },
    };
    const { form, initValue1, initValue2, initValueList } = this.props;
    const { getFieldDecorator } = form; // 校驗控件
    return(
      <Form style={{backgroundColor: '#fff', padding: '20px'}}> <FormItem {...formItemLayout} label={`相關數量`} > {getFieldDecorator(`amount`,{ rules: [{ message: '必填字段!', required: true }], initialValue: initValue1 ? initValue1 : undefined })( <Input placeholder="請輸入"/> )} </FormItem> <FormItem {...formItemLayout} label={`選擇相關名稱`} > {getFieldDecorator(`name`,{ rules: [{ message: '必填字段!', required: false }], initialValue: initValue2 ? initValue2 : undefined })( <Select placeholder="請選擇" onChange={this.handleSelectChange} > { initValueList && initValueList.map((x, i) => ( <Option value={x.Id} key={i}>{x.name}</Option> )) } </Select> )} </FormItem> </Form> ) } } export default Form.create()(Forms); //建立form實例 複製代碼

Form子組件,接收父組件傳過來的初始數據,組件中getItemsValue自定義方法返回表單的值,須要在父組件中調用。react

父組件:antd

import React, { Component } from 'react';
import { Modal, Button } from 'antd';
import Forms from './Forms'

export default class Modals extends Component {
    constructor(props) {
        super(props);
        this.state = {
          visible: false,
          initValue1: 0,
          initValue2: 'myName',
          initValueList: ["李雲龍", "李榮基", "李達"]
        };
    }
    handleClick = () => {
        this.setState({
            visible: true
        })
    };
    handleCreate = () => {
        let values = this.formRef.getItemsValue();
        // 獲取到子組件form的值,作進一步操做
        this.setState({
            visible: false
        })
    };
    render() {
        return (
            <section> <Modal visible={this.state.visible} title="編輯" onOk={this.handleCreate} onCancel={() => { this.setState({ visible: false }); }} okText="保存" cancelText="取消" > <Forms initValue1={initValue1} initValue2={initValue2} initValueList={initValueList} wrappedComponentRef={(form) => this.formRef = form} /> </Modal> <Button onClick={()=>{ this.handleClick }}>點擊彈框</Button> </section> ); } } 複製代碼

這裏關鍵的是使用wrappedComponentRef屬性拿到這個Form的ref,簡單的理解爲拿到子組件的form實例,所以,能夠在handleCreate函數中經過this.formRef.getItemsValue()調用自子組件的方法獲取返回的form值。至此,上面的問題就解決了。app

關於wrappedComponentRef的描述詳見antd官網描述函數

相關文章
相關標籤/搜索