fix: fix FormModel.validateIn only match one pattern (#124)

This commit is contained in:
YuanHeDx 2025-04-03 11:34:56 +08:00 committed by GitHub
parent 03dab3a764
commit 707760a8d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 44 additions and 16 deletions

View File

@ -195,6 +195,30 @@ describe('FieldModel', () => {
expect(other.validate).toHaveBeenCalledTimes(0);
});
it('should validate when multiple pattern match ', async () => {
const validate1 = vi.fn();
const validate2 = vi.fn();
formModel.init({
validateTrigger: ValidateTrigger.onChange,
validate: {
'a.*.input': validate1,
'a.1.input': validate2,
},
initialValues: {
a: [{ input: '0' }, { input: '1' }],
},
});
const root = formModel.createField('a');
const i0 = formModel.createField('a.0.input');
const i1 = formModel.createField('a.1.input');
formModel.setValueIn('a.1.input', 'xxx');
expect(validate1).toHaveBeenCalledTimes(1);
expect(validate2).toHaveBeenCalledTimes(1);
});
// 暂时注释了从 parent 触发validate 的能力,所以注释这个单测
// it('can trigger validate from parent', async () => {
// formModel.init({

View File

@ -7,9 +7,9 @@ import { toFeedback } from '../utils/validate';
import { FieldModelState, FieldName, FieldValue, Ref } from '../types/field';
import {
Errors,
FeedbackLevel,
FieldError,
FieldWarning,
isFieldWarning,
Validate,
ValidateTrigger,
Warnings,
@ -343,24 +343,26 @@ export class FieldModel<TValue extends FieldValue = FieldValue> implements Dispo
errors?: FieldError[];
warnings?: FieldWarning[];
}> {
const errors: FieldError[] = [];
const warnings: FieldWarning[] = [];
let errors: FieldError[] = [];
let warnings: FieldWarning[] = [];
const result = await this.form.validateIn(this.name);
if (!result) {
const results = await this.form.validateIn(this.name);
if (!results?.length) {
return {};
} else {
const feedback = toFeedback(result, this.name);
const feedbacks = results.map((result) => toFeedback(result, this.name)).filter(Boolean) as (
| FieldError
| FieldWarning
)[];
if (!feedback) {
if (!feedbacks?.length) {
return {};
}
if (isFieldWarning(feedback)) {
warnings.push(feedback);
} else {
errors.push(feedback);
}
const groupedFeedbacks = groupBy(feedbacks, 'level');
warnings = warnings.concat(groupedFeedbacks[FeedbackLevel.Warning] as FieldWarning[]);
errors = errors.concat(groupedFeedbacks[FeedbackLevel.Error] as FieldError[]);
}
return { errors, warnings };

View File

@ -239,12 +239,12 @@ export class FormModel<TValues = any> implements Disposable {
return;
}
const validateKey = Object.keys(this._options.validate).find((pattern) =>
const validateKeys = Object.keys(this._options.validate).filter((pattern) =>
Glob.isMatch(pattern, name)
);
if (validateKey) {
const validate = this._options.validate[validateKey];
const validatePromises = validateKeys.map(async (validateKey) => {
const validate = this._options.validate![validateKey];
return validate({
value: this.getValueIn(name),
@ -252,7 +252,9 @@ export class FormModel<TValues = any> implements Disposable {
context: this.context,
name,
});
}
});
return Promise.all(validatePromises);
}
async validate(): Promise<FormValidateReturn> {