diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index 594eb6f36..05347a0c9 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -16,6 +16,7 @@ const jestConfig = { // testMatch: ['**/prop.test.ts'], // testMatch: ['(/tests?/.*(test))\\.[jt]s$'], // testMatch: ['**/document/node/node.add.test.ts'], + // testMatch: ['**/setting-field.test.ts'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, ], diff --git a/packages/designer/src/designer/setting/setting-prop-entry.ts b/packages/designer/src/designer/setting/setting-prop-entry.ts index 271ea4f3c..d6904f0c8 100644 --- a/packages/designer/src/designer/setting/setting-prop-entry.ts +++ b/packages/designer/src/designer/setting/setting-prop-entry.ts @@ -9,10 +9,10 @@ import { ISettingTopEntry } from './setting-top-entry'; import { ISettingField, isSettingField } from './setting-field'; export interface ISettingPropEntry extends ISettingEntry { - get props(): ISettingTopEntry; - readonly isGroup: boolean; + get props(): ISettingTopEntry; + get name(): string | number | undefined; valueChange(options: IPublicTypeSetValueOptions): void; @@ -75,7 +75,7 @@ export class SettingPropEntry implements ISettingPropEntry { @computed get path() { const path = this.parent.path.slice(); - if (this.type === 'field' && this.name) { + if (this.type === 'field' && this.name?.toString()) { path.push(this.name); } return path; @@ -191,7 +191,7 @@ export class SettingPropEntry implements ISettingPropEntry { */ getValue(): any { let val: any; - if (this.type === 'field' && this.name) { + if (this.type === 'field' && this.name?.toString()) { val = this.parent.getPropValue(this.name); } const { getValue } = this.extraProps; @@ -209,7 +209,7 @@ export class SettingPropEntry implements ISettingPropEntry { setValue(val: any, isHotValue?: boolean, force?: boolean, extraOptions?: IPublicTypeSetValueOptions) { const oldValue = this.getValue(); if (this.type === 'field') { - this.name && this.parent.setPropValue(this.name, val); + this.name?.toString() && this.parent.setPropValue(this.name, val); } const { setValue } = this.extraProps; @@ -233,7 +233,7 @@ export class SettingPropEntry implements ISettingPropEntry { */ clearValue() { if (this.type === 'field') { - this.name && this.parent.clearPropValue(this.name); + this.name?.toString() && this.parent.clearPropValue(this.name); } const { setValue } = this.extraProps; if (setValue) { @@ -395,6 +395,6 @@ export class SettingPropEntry implements ISettingPropEntry { } internalToShellField(): IPublicModelSettingField { - return this.designer!.shellModelFactory.createSettingField(this);; + return this.designer!.shellModelFactory.createSettingField(this); } } diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 4ff300f36..e1dce17dd 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -155,7 +155,7 @@ export interface IBaseNode { it('常规方法', () => { // 普通 field - const settingEntry = mockNode.settingEntry as SettingTopEntry; - const field = settingEntry.get('behavior') as SettingField; + const settingEntry = mockNode.settingEntry; + const field = settingEntry.get('behavior'); expect(field.title).toBe('默认状态'); expect(field.expanded).toBeTruthy(); field.setExpanded(false); @@ -103,24 +103,24 @@ describe('setting-field 测试', () => { expect(nonExistingField.setter).toBeNull(); // group 类型的 field - const groupField = settingEntry.get('groupkgzzeo41') as SettingField; + const groupField = settingEntry.get('groupkgzzeo41'); expect(groupField.items).toEqual([]); // 有子节点的 field - const objField = settingEntry.get('obj') as SettingField; + const objField = settingEntry.get('obj'); expect(objField.items).toHaveLength(3); expect(objField.getItems()).toHaveLength(3); expect(objField.getItems(x => x.name === 'a')).toHaveLength(1); objField.purge(); expect(objField.items).toHaveLength(0); - const objAField = settingEntry.get('obj.a') as SettingField; + const objAField = settingEntry.get('obj.a'); expect(objAField.setter).toBe('StringSetter'); }); it('setValue / getValue / setHotValue / getHotValue', () => { // 获取已有的 prop const settingEntry = mockNode.settingEntry as SettingTopEntry; - const field = settingEntry.get('behavior') as SettingField; + const field = settingEntry.get('behavior'); // 会读取 extraProps.defaultValue expect(field.getHotValue()).toBe('NORMAL'); @@ -140,11 +140,37 @@ describe('setting-field 测试', () => { // dirty fix list setter field.setHotValue([{ __sid__: 1 }]); + + // 数组的 field + const arrField = settingEntry.get('arr'); + const subArrField = arrField.createField({ + name: 0, + title: 'sub', + }); + const subArrField02 = arrField.createField({ + name: 1, + title: 'sub', + }); + const subArrField03 = arrField.createField({ + name: '2', + title: 'sub', + }); + subArrField.setValue({name: '1'}); + expect(subArrField.path).toEqual(['arr', 0]); + expect(subArrField02.path).toEqual(['arr', 1]); + subArrField02.setValue({name: '2'}); + expect(subArrField.getValue()).toEqual({name: '1'}); + expect(arrField.getHotValue()).toEqual([{name: '1'}, {name: '2'}]); + subArrField.clearValue(); + expect(subArrField.getValue()).toBeUndefined(); + expect(arrField.getHotValue()).toEqual([undefined, {name: '2'}]); + subArrField03.setValue({name: '3'}); + expect(arrField.getHotValue()).toEqual([undefined, {name: '2'}, {name: '3'}]); }); it('onEffect', async () => { const settingEntry = mockNode.settingEntry as SettingTopEntry; - const field = settingEntry.get('behavior') as SettingField; + const field = settingEntry.get('behavior'); const mockFn = jest.fn(); diff --git a/packages/types/src/shell/model/node.ts b/packages/types/src/shell/model/node.ts index 1cbf63e13..0255376ae 100644 --- a/packages/types/src/shell/model/node.ts +++ b/packages/types/src/shell/model/node.ts @@ -299,7 +299,7 @@ export interface IBaseModelNode< * @param path 属性路径,支持 a / a.b / a.0 等格式 * @param createIfNone 如果不存在,是否新建,默认为 true */ - getProp(path: string, createIfNone?: boolean): Prop | null; + getProp(path: string | number, createIfNone?: boolean): Prop | null; /** * 获取指定 path 的属性模型实例值 @@ -336,7 +336,7 @@ export interface IBaseModelNode< * @param path 属性路径,支持 a / a.b / a.0 等格式 * @param value 值 */ - setPropValue(path: string, value: IPublicTypeCompositeValue): void; + setPropValue(path: string | number, value: IPublicTypeCompositeValue): void; /** * 设置指定 path 的属性模型实例值