From 1ac87fb4540f6ce99486b1fb881f3ccefd2a4691 Mon Sep 17 00:00:00 2001 From: Janry Date: Mon, 11 Oct 2021 11:00:38 +0800 Subject: [PATCH] fix(core): fix validate lifecycle wrong trigger in skip digest (#2279) --- packages/core/src/__tests__/form.spec.ts | 52 ++++++++++++++++++++++-- packages/core/src/shared/internals.ts | 22 ++++++---- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/packages/core/src/__tests__/form.spec.ts b/packages/core/src/__tests__/form.spec.ts index 2a298e4b8a3..ad28a904b7a 100644 --- a/packages/core/src/__tests__/form.spec.ts +++ b/packages/core/src/__tests__/form.spec.ts @@ -1,5 +1,6 @@ import { createForm } from '../' import { + onFieldValidateStart, onFieldValueChange, onFormInitialValuesChange, onFormValuesChange, @@ -1246,7 +1247,16 @@ test('designable form', () => { }) test('validate will skip display none', async () => { - const form = attach(createForm()) + const validateA = jest.fn() + const validateB = jest.fn() + const form = attach( + createForm({ + effects() { + onFieldValidateStart('aa', validateA) + onFieldValidateStart('bb', validateB) + }, + }) + ) const validator = jest.fn() const aa = attach( form.createField({ @@ -1288,6 +1298,8 @@ test('validate will skip display none', async () => { }, ]) } + expect(validateA).toBeCalledTimes(1) + expect(validateB).toBeCalledTimes(1) expect(aa.invalid).toBeTruthy() expect(bb.invalid).toBeTruthy() expect(validator).toBeCalledTimes(2) @@ -1306,18 +1318,31 @@ test('validate will skip display none', async () => { }, ]) } + expect(validateA).toBeCalledTimes(1) + expect(validateB).toBeCalledTimes(2) expect(aa.invalid).toBeFalsy() expect(bb.invalid).toBeTruthy() expect(validator).toBeCalledTimes(3) bb.display = 'none' await form.validate() + expect(validateA).toBeCalledTimes(1) + expect(validateB).toBeCalledTimes(2) expect(aa.invalid).toBeFalsy() expect(bb.invalid).toBeFalsy() expect(validator).toBeCalledTimes(3) }) test('validate will skip unmounted', async () => { - const form = attach(createForm()) + const validateA = jest.fn() + const validateB = jest.fn() + const form = attach( + createForm({ + effects() { + onFieldValidateStart('aa', validateA) + onFieldValidateStart('bb', validateB) + }, + }) + ) const validator = jest.fn() const aa = attach( form.createField({ @@ -1359,6 +1384,8 @@ test('validate will skip unmounted', async () => { }, ]) } + expect(validateA).toBeCalledTimes(1) + expect(validateB).toBeCalledTimes(1) expect(aa.invalid).toBeTruthy() expect(bb.invalid).toBeTruthy() expect(validator).toBeCalledTimes(2) @@ -1377,18 +1404,31 @@ test('validate will skip unmounted', async () => { }, ]) } + expect(validateA).toBeCalledTimes(1) + expect(validateB).toBeCalledTimes(2) expect(aa.invalid).toBeFalsy() expect(bb.invalid).toBeTruthy() expect(validator).toBeCalledTimes(3) bb.onUnmount() await form.validate() + expect(validateA).toBeCalledTimes(1) + expect(validateB).toBeCalledTimes(2) expect(aa.invalid).toBeFalsy() expect(bb.invalid).toBeFalsy() expect(validator).toBeCalledTimes(3) }) test('validate will skip uneditable', async () => { - const form = attach(createForm()) + const validateA = jest.fn() + const validateB = jest.fn() + const form = attach( + createForm({ + effects() { + onFieldValidateStart('aa', validateA) + onFieldValidateStart('bb', validateB) + }, + }) + ) const validator = jest.fn() const aa = attach( form.createField({ @@ -1430,6 +1470,8 @@ test('validate will skip uneditable', async () => { }, ]) } + expect(validateA).toBeCalledTimes(1) + expect(validateB).toBeCalledTimes(1) expect(aa.invalid).toBeTruthy() expect(bb.invalid).toBeTruthy() expect(validator).toBeCalledTimes(2) @@ -1448,11 +1490,15 @@ test('validate will skip uneditable', async () => { }, ]) } + expect(validateA).toBeCalledTimes(1) + expect(validateB).toBeCalledTimes(2) expect(aa.invalid).toBeFalsy() expect(bb.invalid).toBeTruthy() expect(validator).toBeCalledTimes(3) bb.editable = false await form.validate() + expect(validateA).toBeCalledTimes(1) + expect(validateB).toBeCalledTimes(2) expect(aa.invalid).toBeFalsy() expect(bb.invalid).toBeFalsy() expect(validator).toBeCalledTimes(3) diff --git a/packages/core/src/shared/internals.ts b/packages/core/src/shared/internals.ts index 8db6e021486..26685b82bfe 100644 --- a/packages/core/src/shared/internals.ts +++ b/packages/core/src/shared/internals.ts @@ -255,13 +255,6 @@ export const validateToFeedbacks = async ( field: Field, triggerType?: ValidatorTriggerType ) => { - if ( - field.pattern !== 'editable' || - field.display !== 'visible' || - field.unmounted - ) - return {} - const results = await validate(field.value, field.validator, { triggerType, validateFirst: field.props.validateFirst || field.form.props.validateFirst, @@ -880,6 +873,14 @@ export const batchValidate = async ( triggerType?: ValidatorTriggerType ) => { if (isForm(target)) target.setValidating(true) + else { + if ( + target.pattern !== 'editable' || + target.display !== 'visible' || + target.unmounted + ) + return + } const tasks = [] target.query(pattern).forEach((field) => { if (!isVoidField(field)) { @@ -932,6 +933,13 @@ export const validateSelf = batch.bound( target.notify(LifeCycleTypes.ON_FIELD_VALIDATE_FAILED) } } + + if ( + target.pattern !== 'editable' || + target.display !== 'visible' || + target.unmounted + ) + return {} start() if (!triggerType) { const allTriggerTypes = parseValidatorDescriptions(target.validator).map(