From cea638cda5158d0fe9c990c609cd2ef874099238 Mon Sep 17 00:00:00 2001 From: liuwei Date: Thu, 5 Sep 2024 09:45:20 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=20=E6=94=AF=E6=8C=81=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E9=85=8D=E7=BD=AE=20validate=20=E5=9C=A8=E5=93=AA?= =?UTF-8?q?=E4=BA=9B=20pattern=20&=20display=20=E4=B8=8B=E7=94=9F=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/docs/api/models/Form.md | 2 + packages/core/docs/api/models/Form.zh-CN.md | 2 + packages/core/src/__tests__/field.spec.ts | 47 +++++++++++++++++++++ packages/core/src/shared/internals.ts | 15 ++++++- packages/core/src/types.ts | 4 ++ 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/packages/core/docs/api/models/Form.md b/packages/core/docs/api/models/Form.md index 482f71d96e0..b6cb4878294 100644 --- a/packages/core/docs/api/models/Form.md +++ b/packages/core/docs/api/models/Form.md @@ -789,6 +789,8 @@ interface IFieldFactoryProps { readPretty?: boolean //Whether the field is in the read state dataSource?: any[] //Field data source validateFirst?: boolean //Does the field verification only verify the first illegal rule? + validatePattern?: ('editable' | 'disabled' | 'readOnly' | 'readPretty')[] // Which patterns the validator can run in + validateDisplay?: ('none' | 'hidden' | 'visible')[] // Which displays the validator can run in validator?: FieldValidator //Field validator decorator?: any[] //Field decorator, the first element represents the component reference, the second element represents the component attribute component?: any[] //Field component, the first element represents the component reference, the second element represents the component attribute diff --git a/packages/core/docs/api/models/Form.zh-CN.md b/packages/core/docs/api/models/Form.zh-CN.md index 557c26516e8..88db1f3fa2b 100644 --- a/packages/core/docs/api/models/Form.zh-CN.md +++ b/packages/core/docs/api/models/Form.zh-CN.md @@ -789,6 +789,8 @@ interface IFieldFactoryProps { readPretty?: boolean //字段是否为阅读态 dataSource?: any[] //字段数据源 validateFirst?: boolean //字段校验是否只校验第一个非法规则 + validatePattern?: ('editable' | 'disabled' | 'readOnly' | 'readPretty')[] // validator 可以在哪些 pattern 下运行 + validateDisplay?: ('none' | 'hidden' | 'visible')[] // validator 可以在哪些 display 下运行 validator?: FieldValidator //字段校验器 decorator?: any[] //字段装饰器,第一个元素代表组件引用,第二个元素代表组件属性 component?: any[] //字段组件,第一个元素代表组件引用,第二个元素代表组件属性 diff --git a/packages/core/src/__tests__/field.spec.ts b/packages/core/src/__tests__/field.spec.ts index ee8c95602e1..e8a20f3dc6b 100644 --- a/packages/core/src/__tests__/field.spec.ts +++ b/packages/core/src/__tests__/field.spec.ts @@ -2402,3 +2402,50 @@ test('onFocus and onBlur with invalid target value', async () => { 'The field value is a invalid url', ]) }) + +test('validatePattern and validateDisplay', async () => { + const form = attach( + createForm({ + validatePattern: ['editable'], + validateDisplay: ['visible'], + }) + ) + const field1 = attach( + form.createField({ + name: 'a', + required: true, + }) + ) + const field2 = attach( + form.createField({ + name: 'b', + required: true, + validatePattern: ['readOnly'], + validateDisplay: ['hidden'], + }) + ) + const field3 = attach( + form.createField({ + name: 'c', + required: true, + validatePattern: ['readOnly', 'editable'], + validateDisplay: ['hidden', 'visible'], + }) + ) + + try { + await form.validate() + } catch {} + expect(field1.selfErrors.length).toBe(1) + expect(field2.selfErrors.length).toBe(0) + expect(field3.selfErrors.length).toBe(1) + + form.setPattern('readOnly') + form.setDisplay('hidden') + try { + await form.validate() + } catch {} + expect(field1.selfErrors.length).toBe(0) + expect(field2.selfErrors.length).toBe(1) + expect(field3.selfErrors.length).toBe(1) +}) diff --git a/packages/core/src/shared/internals.ts b/packages/core/src/shared/internals.ts index ea9d586f83d..e9b899f85ce 100644 --- a/packages/core/src/shared/internals.ts +++ b/packages/core/src/shared/internals.ts @@ -880,6 +880,17 @@ export const batchSubmit = async ( return results } +const shouldValidate = (field: Field) => { + const validatePattern = field.props.validatePattern ?? + field.form.props.validatePattern ?? ['editable'] + const validateDisplay = field.props.validateDisplay ?? + field.form.props.validateDisplay ?? ['visible'] + return ( + validatePattern.includes(field.pattern) && + validateDisplay.includes(field.display) + ) +} + export const batchValidate = async ( target: Form | Field, pattern: FormPathPattern, @@ -887,7 +898,7 @@ export const batchValidate = async ( ) => { if (isForm(target)) target.setValidating(true) else { - if (target.pattern !== 'editable' || target.display !== 'visible') return + if (!shouldValidate(target)) return } const tasks = [] target.query(pattern).forEach((field) => { @@ -945,7 +956,7 @@ export const validateSelf = batch.bound( } } - if (target.pattern !== 'editable' || target.display !== 'visible') return {} + if (!shouldValidate(target)) return {} start() if (!triggerType) { const allTriggerTypes = parseValidatorDescriptions( diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 4c5360c7e20..e0716a8cb6a 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -247,6 +247,8 @@ export interface IFormProps { readPretty?: boolean effects?: (form: Form) => void validateFirst?: boolean + validatePattern?: FormPatternTypes[] + validateDisplay?: FormDisplayTypes[] designable?: boolean } @@ -349,6 +351,8 @@ export interface IFieldProps< readPretty?: boolean dataSource?: FieldDataSource validateFirst?: boolean + validatePattern?: FieldPatternTypes[] + validateDisplay?: FieldDisplayTypes[] validator?: FieldValidator decorator?: FieldDecorator component?: FieldComponent