소스 검색

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

YuanHeDx 9 달 전
부모
커밋
707760a8d0

+ 24 - 0
packages/node-engine/form/__tests__/field-model.test.ts

@@ -195,6 +195,30 @@ describe('FieldModel', () => {
       expect(other.validate).toHaveBeenCalledTimes(0);
       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 的能力,所以注释这个单测
     // 暂时注释了从 parent 触发validate 的能力,所以注释这个单测
     // it('can trigger validate from parent', async () => {
     // it('can trigger validate from parent', async () => {
     //   formModel.init({
     //   formModel.init({

+ 14 - 12
packages/node-engine/form/src/core/field-model.ts

@@ -7,9 +7,9 @@ import { toFeedback } from '../utils/validate';
 import { FieldModelState, FieldName, FieldValue, Ref } from '../types/field';
 import { FieldModelState, FieldName, FieldValue, Ref } from '../types/field';
 import {
 import {
   Errors,
   Errors,
+  FeedbackLevel,
   FieldError,
   FieldError,
   FieldWarning,
   FieldWarning,
-  isFieldWarning,
   Validate,
   Validate,
   ValidateTrigger,
   ValidateTrigger,
   Warnings,
   Warnings,
@@ -343,24 +343,26 @@ export class FieldModel<TValue extends FieldValue = FieldValue> implements Dispo
     errors?: FieldError[];
     errors?: FieldError[];
     warnings?: FieldWarning[];
     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 {};
       return {};
     } else {
     } 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 {};
         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 };
     return { errors, warnings };

+ 6 - 4
packages/node-engine/form/src/core/form-model.ts

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