diff --git a/packages/core/docs/api/models/Field.md b/packages/core/docs/api/models/Field.md index 47241f3b3df..ad5cfac6c66 100644 --- a/packages/core/docs/api/models/Field.md +++ b/packages/core/docs/api/models/Field.md @@ -665,6 +665,34 @@ interface match { FormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern) +### inject + +#### Description + +Inject executable methods into field models + +#### Signature + +```ts +interface inject { + (actions: Record any>): void +} +``` + +### invoke + +#### Description + +Invoke an executable method injected by the field model via inject + +#### Signature + +```ts +interface invoke { + (name: string, ...args: any[]): any +} +``` + ## Types of diff --git a/packages/core/docs/api/models/Field.zh-CN.md b/packages/core/docs/api/models/Field.zh-CN.md index 59b4c82125c..5a3039f4b7c 100644 --- a/packages/core/docs/api/models/Field.zh-CN.md +++ b/packages/core/docs/api/models/Field.zh-CN.md @@ -665,6 +665,34 @@ interface match { FormPathPattern API 参考 [FormPath](/api/entry/form-path#formpathpattern) +### inject + +#### 描述 + +给字段模型注入可执行方法 + +#### 签名 + +```ts +interface inject { + (actions: Record any>): void +} +``` + +### invoke + +#### 描述 + +调用字段模型通过 inject 注入的可执行方法 + +#### 签名 + +```ts +interface invoke { + (name: string, ...args: any[]): any +} +``` + ## 类型 diff --git a/packages/core/docs/api/models/VoidField.md b/packages/core/docs/api/models/VoidField.md index d16a0998403..ab859f75971 100644 --- a/packages/core/docs/api/models/VoidField.md +++ b/packages/core/docs/api/models/VoidField.md @@ -333,6 +333,34 @@ interface match { FormPathPattern API Reference [FormPath](/api/entry/form-path#formpathpattern) +### inject + +#### Description + +Inject executable methods into field models + +#### Signature + +```ts +interface inject { + (actions: Record any>): void +} +``` + +### invoke + +#### Description + +Invoke an executable method injected by the field model via inject + +#### Signature + +```ts +interface invoke { + (name: string, ...args: any[]): any +} +``` + ## Types of diff --git a/packages/core/docs/api/models/VoidField.zh-CN.md b/packages/core/docs/api/models/VoidField.zh-CN.md index 3bd6b6480bd..284d4cee2a7 100644 --- a/packages/core/docs/api/models/VoidField.zh-CN.md +++ b/packages/core/docs/api/models/VoidField.zh-CN.md @@ -333,6 +333,34 @@ interface match { FormPathPattern API 参考 [FormPath](/api/entry/form-path#formpathpattern) +### inject + +#### 描述 + +给字段模型注入可执行方法 + +#### 签名 + +```ts +interface inject { + (actions: Record any>): void +} +``` + +### invoke + +#### 描述 + +调用字段模型通过 inject 注入的可执行方法 + +#### 签名 + +```ts +interface invoke { + (name: string, ...args: any[]): any +} +``` + ## 类型 diff --git a/packages/core/src/__tests__/field.spec.ts b/packages/core/src/__tests__/field.spec.ts index 20dc312fe26..da144d92edc 100644 --- a/packages/core/src/__tests__/field.spec.ts +++ b/packages/core/src/__tests__/field.spec.ts @@ -2277,3 +2277,21 @@ test('onFieldReact with field destroyed', () => { obs.value = '111' expect(fn).toBeCalledTimes(2) }) + +test('field actions', () => { + const form = attach(createForm()) + const aa = attach( + form.createField({ + name: 'aa', + }) + ) + expect(aa.actions).toEqual({}) + aa.inject({ + test: () => 123, + }) + expect(aa.invoke('test')).toEqual(123) + aa.inject({ + test: () => 321, + }) + expect(aa.invoke('test')).toEqual(321) +}) diff --git a/packages/core/src/models/BaseField.ts b/packages/core/src/models/BaseField.ts index f59001a02af..8b6f33c1498 100644 --- a/packages/core/src/models/BaseField.ts +++ b/packages/core/src/models/BaseField.ts @@ -1,4 +1,11 @@ -import { FormPath, FormPathPattern, isValid, toArr } from '@formily/shared' +import { + FormPath, + FormPathPattern, + isValid, + toArr, + each, + isFn, +} from '@formily/shared' import { JSXComponent, LifeCycleTypes, @@ -6,6 +13,7 @@ import { FieldPatternTypes, FieldDecorator, FieldComponent, + IFieldActions, } from '../types' import { locateNode, destroy, initFieldUpdate } from '../shared/internals' import { Form } from './Form' @@ -37,6 +45,8 @@ export class BaseField { disposers: (() => void)[] = [] + actions: IFieldActions = {} + locate(address: FormPathPattern) { this.form.fields[address.toString()] = this as any locateNode(this as any, address) @@ -309,4 +319,16 @@ export class BaseField { match = (pattern: FormPathPattern) => { return FormPath.parse(pattern).matchAliasGroup(this.address, this.path) } + + inject = (actions: IFieldActions) => { + each(actions, (action, key) => { + if (isFn(action)) { + this.actions[key] = action + } + }) + } + + invoke = (name: string, ...args: any[]) => { + return this.actions[name]?.(...args) + } } diff --git a/packages/core/src/models/Field.ts b/packages/core/src/models/Field.ts index b3b793f9077..3c89f678674 100644 --- a/packages/core/src/models/Field.ts +++ b/packages/core/src/models/Field.ts @@ -78,7 +78,6 @@ export class Field< feedbacks: IFieldFeedback[] caches: IFieldCaches = {} requests: IFieldRequests = {} - constructor( address: FormPathPattern, props: IFieldProps, diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index c2f01ac00ed..b5e10113cbb 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -433,3 +433,7 @@ export interface IFieldStateGetter { ): ReturnType (pattern: FieldMatchPattern): IGeneralFieldState } + +export interface IFieldActions { + [key: string]: (...args: any[]) => any +}