Skip to content

Commit f3a9b7b

Browse files
committed
fix: update form validate
1 parent 346ab47 commit f3a9b7b

File tree

9 files changed

+502
-266
lines changed

9 files changed

+502
-266
lines changed

antdv-demo

components/form-model/Form.jsx

+89-57
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import warning from '../_util/warning';
88
import FormItem from './FormItem';
99
import { initDefaultProps, getSlot } from '../_util/props-util';
1010
import { ConfigConsumerProps } from '../config-provider';
11-
import { getParams } from './utils';
11+
import { getNamePath, containsNamePath } from './utils/valueUtil';
12+
import { defaultValidateMessages } from './utils/messages';
13+
import { allPromiseFinish } from './utils/asyncUtil';
14+
import { toArray } from './utils/typeUtil';
1215

1316
export const FormProps = {
1417
layout: PropTypes.oneOf(['horizontal', 'inline', 'vertical']),
@@ -66,6 +69,7 @@ const Form = {
6669
created() {
6770
this.fields = [];
6871
this.form = undefined;
72+
this.lastValidatePromise = null;
6973
provide('FormContext', this);
7074
},
7175
setup() {
@@ -100,12 +104,16 @@ const Form = {
100104
e.preventDefault();
101105
e.stopPropagation();
102106
this.$emit('submit', e);
103-
const res = this.validate();
107+
const res = this.validateFields();
104108
res
105109
.then(values => {
110+
// eslint-disable-next-line no-console
111+
console.log('values', values);
106112
this.$emit('finish', values);
107113
})
108114
.catch(errors => {
115+
// eslint-disable-next-line no-console
116+
console.log('errors', errors);
109117
this.handleFinishFailed(errors);
110118
});
111119
},
@@ -179,74 +187,98 @@ const Form = {
179187
// }
180188
},
181189
scrollToField() {},
182-
getFieldsValue(allFields) {
190+
// TODO
191+
// eslint-disable-next-line no-unused-vars
192+
getFieldsValue(nameList) {
183193
const values = {};
184-
allFields.forEach(({ prop, fieldValue }) => {
194+
this.fields.forEach(({ prop, fieldValue }) => {
185195
values[prop] = fieldValue;
186196
});
187197
return values;
188198
},
189-
validateFields() {
190-
return this.validateField(...arguments);
191-
},
192-
validateField(ns, opt, cb) {
193-
const pending = new Promise((resolve, reject) => {
194-
const params = getParams(ns, opt, cb);
195-
const { names, options } = params;
196-
let { callback } = params;
197-
if (!callback || typeof callback === 'function') {
198-
const oldCb = callback;
199-
callback = (errorFields, values) => {
200-
if (oldCb) {
201-
oldCb(errorFields, values);
202-
} else if (errorFields) {
203-
reject({ errorFields, values });
204-
} else {
205-
resolve(values);
206-
}
207-
};
199+
validateFields(nameList, options) {
200+
if (!this.model) {
201+
warning(false, 'Form', 'model is required for validateFields to work.');
202+
return;
203+
}
204+
const provideNameList = !!nameList;
205+
const namePathList = provideNameList ? toArray(nameList).map(getNamePath) : [];
206+
207+
// Collect result in promise list
208+
const promiseList = [];
209+
210+
this.fields.forEach(field => {
211+
// Add field if not provide `nameList`
212+
if (!provideNameList) {
213+
namePathList.push(field.getNamePath());
208214
}
209-
const allFields = names
210-
? this.fields.filter(field => names.indexOf(field.prop) !== -1)
211-
: this.fields;
212-
const fields = allFields.filter(field => {
213-
const rules = field.getFilteredRule('');
214-
return rules && rules.length;
215-
});
216-
if (!fields.length) {
217-
callback(null, this.getFieldsValue(allFields));
215+
216+
// Skip if without rule
217+
if (!field.getRules().length) {
218218
return;
219219
}
220-
if (!('firstFields' in options)) {
221-
options.firstFields = allFields.filter(field => {
222-
return !!field.validateFirst;
220+
221+
const fieldNamePath = field.getNamePath();
222+
223+
// Add field validate rule in to promise list
224+
if (!provideNameList || containsNamePath(namePathList, fieldNamePath)) {
225+
const promise = field.validateRules({
226+
validateMessages: {
227+
...defaultValidateMessages,
228+
...this.validateMessages,
229+
},
230+
...options,
223231
});
232+
233+
// Wrap promise with field
234+
promiseList.push(
235+
promise
236+
.then(() => ({ name: fieldNamePath, errors: [] }))
237+
.catch(errors =>
238+
Promise.reject({
239+
name: fieldNamePath,
240+
errors,
241+
}),
242+
),
243+
);
224244
}
225-
let fieldsErrors = {};
226-
let valid = true;
227-
let count = 0;
228-
const promiseList = [];
229-
fields.forEach(field => {
230-
const promise = field.validate('', errors => {
231-
if (errors) {
232-
valid = false;
233-
fieldsErrors[field.prop] = errors;
234-
}
245+
});
246+
247+
const summaryPromise = allPromiseFinish(promiseList);
248+
this.lastValidatePromise = summaryPromise;
249+
250+
// // Notify fields with rule that validate has finished and need update
251+
// summaryPromise
252+
// .catch(results => results)
253+
// .then(results => {
254+
// const resultNamePathList = results.map(({ name }) => name);
255+
// // eslint-disable-next-line no-console
256+
// console.log(resultNamePathList);
257+
// });
235258

236-
if (++count === fields.length) {
237-
callback(valid ? null : fieldsErrors, this.getFieldsValue(fields));
238-
}
259+
const returnPromise = summaryPromise
260+
.then(() => {
261+
if (this.lastValidatePromise === summaryPromise) {
262+
return Promise.resolve(this.getFieldsValue(namePathList));
263+
}
264+
return Promise.reject([]);
265+
})
266+
.catch(results => {
267+
const errorList = results.filter(result => result && result.errors.length);
268+
return Promise.reject({
269+
values: this.getFieldsValue(namePathList),
270+
errorFields: errorList,
271+
outOfDate: this.lastValidatePromise !== summaryPromise,
239272
});
240-
promiseList.push(promise.then(() => {}));
241273
});
242-
});
243-
pending.catch(e => {
244-
if (console.error && process.env.NODE_ENV !== 'production') {
245-
console.error(e);
246-
}
247-
return e;
248-
});
249-
return pending;
274+
275+
// Do not throw in console
276+
returnPromise.catch(e => e);
277+
278+
return returnPromise;
279+
},
280+
validateField() {
281+
return this.validateFields(...arguments);
250282
},
251283
},
252284

0 commit comments

Comments
 (0)