diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 262557433..d0965ccf6 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -15,6 +15,7 @@ import { NodeStatus, CompositeValue, GlobalEvent, + ComponentAction, } from '@ali/lowcode-types'; import { compatStage } from '@ali/lowcode-utils'; import { SettingTopEntry } from '@ali/lowcode-designer'; @@ -868,10 +869,17 @@ export class Node { /** * 是否可执行某action */ - canPerformAction(action: string): boolean { + canPerformAction(actionName: string): boolean { const availableActions = - this.componentMeta?.availableActions?.map((action) => action.name) || []; - return availableActions.indexOf(action) >= 0; + this.componentMeta?.availableActions?.filter((action: ComponentAction) => { + const { condition } = action; + return typeof condition === 'function' ? + condition(this) !== false : + condition !== false; + }) + .map((action: ComponentAction) => action.name) || []; + + return availableActions.indexOf(actionName) >= 0; } // ======= compatible apis ==== diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 5b533df67..ac836fb06 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -375,8 +375,14 @@ export class Prop implements IPropParent { return (this.parent.path || []).concat(this.key as string); } + /** + * 构造 items 属性,同时构造 maps 属性 + */ @computed private get items(): Prop[] | null { - if (this._items) return this._items; + // 当类型为 list 时,只要有 _items,直接返回,不再重新构造 + if (this._type === 'list' && this._items) return this._items; + // 当类型为 map 时,_items 和 _maps 理论上都应该存在,数量一致时,可以不再重新构造 + if (this._type === 'map' && this._items && this._items.length === this._maps?.size) return this._items; return runInAction(() => { let items: Prop[] | null = []; if (this._type === 'list') { @@ -451,7 +457,7 @@ export class Prop implements IPropParent { } if (createIfNone) { - prop = new Prop(this, nest ? {} : UNSET, entry); + prop = new Prop(this, UNSET, entry); this.set(entry, prop, true); if (nest) { return prop.get(nest, true); @@ -476,10 +482,10 @@ export class Prop implements IPropParent { */ @action delete(prop: Prop): void { - if (this.items) { - const i = this.items.indexOf(prop); + if (this._items) { + const i = this._items.indexOf(prop); if (i > -1) { - this.items.slice(i, 1); + this._items.splice(i, 1); prop.purge(); } if (this._maps && prop.key) { @@ -558,8 +564,9 @@ export class Prop implements IPropParent { } else { items[key] = prop; } + this._items = items; } else if (this.type === 'map') { - const { maps } = this; + const maps = this._maps || new Map(); const orig = maps?.get(key); if (orig) { // replace @@ -574,6 +581,7 @@ export class Prop implements IPropParent { this._items = items; maps?.set(key, prop); } + this._maps = maps; } /* istanbul ignore next */ else { return null; } diff --git a/packages/designer/src/document/node/props/props.ts b/packages/designer/src/document/node/props/props.ts index 66c646217..b0c7a082d 100644 --- a/packages/designer/src/document/node/props/props.ts +++ b/packages/designer/src/document/node/props/props.ts @@ -202,7 +202,7 @@ export class Props implements IPropParent { let prop = this.maps.get(entry); if (!prop && createIfNone) { - prop = new Prop(this, nest ? {} : UNSET, entry); + prop = new Prop(this, UNSET, entry); this.items.push(prop); } diff --git a/packages/designer/tests/document/node/props/prop.test.ts b/packages/designer/tests/document/node/props/prop.test.ts index 76ed65af6..3e52f92a9 100644 --- a/packages/designer/tests/document/node/props/prop.test.ts +++ b/packages/designer/tests/document/node/props/prop.test.ts @@ -394,7 +394,11 @@ describe('Prop 类测试', () => { prop.unset(); prop.set(0, true); expect(prop.set('x', 'invalid')).toBeNull(); - expect(prop.get(0).getValue()).toBeUndefined(); + expect(prop.get(0).getValue()).toBeTruthy(); + + // map / list 级联测试 + prop.get('loopArgs.0', true).setValue('newItem');; + expect(prop.get('loopArgs.0').getValue()).toBe('newItem'); }); it('export', () => { diff --git a/packages/designer/tests/document/node/props/props.test.ts b/packages/designer/tests/document/node/props/props.test.ts index 360db47eb..6099ce0ac 100644 --- a/packages/designer/tests/document/node/props/props.test.ts +++ b/packages/designer/tests/document/node/props/props.test.ts @@ -77,6 +77,10 @@ describe('Props 类测试', () => { expect(props.get('l').getValue()).toBe('newlyCreatedProp'); expect(props.get('m.m1').getValue()).toBe('newlyCreatedNestedProp'); + + // map / list 级联测试 + props.get('loopArgs.0', true).setValue('newItem'); + expect(props.get('loopArgs.0').getValue()).toBe('newItem'); }); it('export', () => {