解決Antd自定義表單驗證問題

最近項目中遇到一個表單校驗的問題,看官方文檔、網上搜索找了好久,終於找到了解決方案。

先闡述一下問題:

項目中的表單需要多圖片上傳,這個使用Upload組件就OK了,但是表單驗證就出現問題了:
1、首先,上傳圖片項是必須項,不能無圖片提交;
2、已上傳的圖片可以刪除;
3、後端要求提交的圖片爲md5格式,通過上傳接口獲取圖片的md5值,這樣就不能直接使用表單提交時獲取的 value值,因 爲它的值是本地路徑,所以我通過model中上傳圖片獲取md5的值存在model的state中 (這個問題是最棘手的)。


解決問題:

1、首先我自定義了一個表單驗證方法,因爲需要以上傳成功的圖片爲基準。
自定義表單校驗方法:

handleCheckImg = (rule, value, callback) => {
	if (value) {
        const { aware } = this.props;
        const { fileList } = aware;
        const newFileList=fileList.map(item => ({...item}));
        if (!newFileList) {
            callback('請上傳相關圖片');
        } else {
            newFileList.length ? callback() : callback('請上傳相關圖片');
        }
    }
    callback();    // callback方法必須要有,否則會報錯
};

在表單中調用:

<FormItem label="上傳圖片">
    {getFieldDecorator('attachment', {
        rules: [
            { required: true, message: '請上傳相關圖片' },
            { validator: this.handleCheckImg },
        ],
    })(
        <div className="clearfix">
            <Upload {...uploadProps} >
                ......
            </Upload>
        </div>
    )}
</FormItem>

此時表單的驗證規則會調用到自定義的表單驗證方法,但是由於驗證方法默認是在表單onChange的時候調用,而默認onChange時進行表單驗證,在model中用於存放圖片md5值的變量還沒有進行更新這裏就已經進行驗證了,這樣的驗證會導致,即便我已經上傳了一張圖片,頁面上仍然會提示要我上傳相關圖片,刪除圖片卻不會調用到表單驗證。

那要怎麼解決?那就讓我點擊按鈕準備submit時進行表單驗證吧。

2、通過看文檔,表單的getFieldDecorator方法中有個屬性validateTrigger可以設置什麼時候進行表單驗證,默認是onChange。在這裏插入圖片描述
於是我在方法中添加該屬性,設置爲onSubmit:

getFieldDecorator('attachment', {
    rules: [
        { required: true, message: '請上傳相關圖片' },
        { validator: this.handleCheckImg },
    ],
    validateTrigger: 'onSubmit', // 設置進行表單驗證的時機爲onSubmit
    initialValue: detail ? detail.imgList : null,
})

這樣設置了以後雖然可以正常進行表單驗證了,但是,當點擊了一次提交按鈕後,表單驗證過的表單項不會再進行驗證。那萬一我點擊一次提交後,表單中其他表單項有問題,而圖片上傳沒有問題,那我將其他表單項都填好符合驗證格式後,刪除了圖片,再點擊提交按鈕,表單不會再驗證圖片上傳的表單項,這樣就被通過了,不行呀,這是一個bug。
在這裏插入圖片描述
怎麼解決呢?那就點擊提交的時候,都對所有表單項進行一次驗證,無論是否已經驗證過的。

3、Antd框架的validateFields方法中有一個force屬性可以設置是否對已校驗過的表單項再次校驗,默認是false。
在這裏插入圖片描述
於是我在該方法中添加這個屬性,設置爲true。

handleSubmit = (e) => {
  e.preventDefault();
  this.props.form.validateFields({ force: true }, (err, values) => { // 設置force爲true
      ......
  });
};

這樣就解決了我的問題。
在這裏插入圖片描述在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章