diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 148654962..79a3564f9 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -6,7 +6,6 @@ import { valueToSource } from './value-to-source'; import { Props } from './props'; import { SlotNode, Node } from '../node'; import { TransformStage } from '../transform-stage'; -import { getFocusedElement } from 'medium-editor'; export const UNSET = Symbol.for('unset'); export type UNSET = typeof UNSET; @@ -20,35 +19,6 @@ export interface IPropParent { export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot'; -function hasItemsInMetadata(prop: Prop) { - const path = prop.path; - const { configure } = prop.getNode().componentMeta.getMetadata(); - if (!path || path.length === 0) return false; - let props = configure?.props; - while (path.length > 0) { - let name = path.shift(); - let matchedProp = getMatchedProp(props, name!); - if (!matchedProp) return false; - if (path.length === 0) return !!matchedProp?.items; - props = matchedProp.items; - } -} - -function getMatchedProp(props: FieldConfig[] | undefined, name: string): FieldConfig | null { - let found = null; - if (!props) return null; - for (const prop of props) { - if (prop.name === name) { - found = prop; - break; - } else if (prop.type === 'group' && prop.items) { - found = getMatchedProp(prop.items, name); - if (found) return found; - } - } - return found; -} - export class Prop implements IPropParent { readonly isProp = true; @@ -286,19 +256,6 @@ export class Prop implements IPropParent { this.dispose(); - // 将父属性设置成一个对象,得同时把子属性都设值,同时清空其他子属性 - if (this._type === 'map' && isPlainObject(val)) { - this.items?.forEach((item) => { - // @ts-ignore - if ([item.key] in val) { - // @ts-ignore - item.setValue(val[item.key]); - } else { - this.clearPropValue(item.key!); - } - }); - } - if (oldValue !== this._value) { editor?.emit('node.innerProp.change', { node: this.owner, @@ -407,13 +364,8 @@ export class Prop implements IPropParent { return (this.parent.path || []).concat(this.key as string); } - private get items(): Prop[] | null { - // 不在元数据配置项中的,不产生 items - if (!hasItemsInMetadata(this)) return null; - let _items: any; - untracked(() => { - _items = this._items; - }); + @computed private get items(): Prop[] | null { + let _items: any = this._items; if (!_items) { if (this._type === 'list') { const data = this._value; diff --git a/packages/designer/tests/document/node/node.modify.test.ts b/packages/designer/tests/document/node/node.modify.test.ts index 145610899..cd157868b 100644 --- a/packages/designer/tests/document/node/node.modify.test.ts +++ b/packages/designer/tests/document/node/node.modify.test.ts @@ -89,12 +89,12 @@ describe('schema 生成节点模型测试', () => { b: false, c: 'string', }); - // const objAProp = formNode?.getProp('obj.a'); - // const objBProp = formNode?.getProp('obj.b'); - // const objCProp = formNode?.getProp('obj.c'); - // expect(objAProp?.getValue()).toBe(1); - // expect(objBProp?.getValue()).toBe(false); - // expect(objCProp?.getValue()).toBe('string'); + const objAProp = formNode?.getProp('obj.a'); + const objBProp = formNode?.getProp('obj.b'); + const objCProp = formNode?.getProp('obj.c'); + expect(objAProp?.getValue()).toBe(1); + expect(objBProp?.getValue()).toBe(false); + expect(objCProp?.getValue()).toBe('string'); const idProp = formNode?.getExtraProp('extraPropA'); expect(idProp?.getValue()).toBe('extraPropA'); @@ -154,17 +154,17 @@ describe('schema 生成节点模型测试', () => { formNode?.setPropValue('obj.a', 3); formNode?.setPropValue('obj.b', false); formNode?.setPropValue('obj.c', 'string'); - // const objAProp = formNode?.getProp('obj.a'); - // const objBProp = formNode?.getProp('obj.b'); - // const objCProp = formNode?.getProp('obj.c'); - // expect(objAProp?.getValue()).toBe(3); - // expect(objBProp?.getValue()).toBe(false); - // expect(objCProp?.getValue()).toBe('string'); - // expect(objProp?.getValue()).toEqual({ - // a: 3, - // b: false, - // c: 'string', - // }); + const objAProp = formNode?.getProp('obj.a'); + const objBProp = formNode?.getProp('obj.b'); + const objCProp = formNode?.getProp('obj.c'); + expect(objAProp?.getValue()).toBe(3); + expect(objBProp?.getValue()).toBe(false); + expect(objCProp?.getValue()).toBe('string'); + expect(objProp?.getValue()).toEqual({ + a: 3, + b: false, + c: 'string', + }); }); it('修改普通属性,string | number | object,使用 Props 实例接口', () => { @@ -222,17 +222,17 @@ describe('schema 生成节点模型测试', () => { props?.setPropValue('obj.a', 3); props?.setPropValue('obj.b', false); props?.setPropValue('obj.c', 'string'); - // const objAProp = formNode?.getProp('obj.a'); - // const objBProp = formNode?.getProp('obj.b'); - // const objCProp = formNode?.getProp('obj.c'); - // expect(objAProp?.getValue()).toBe(3); - // expect(objBProp?.getValue()).toBe(false); - // expect(objCProp?.getValue()).toBe('string'); - // expect(objProp?.getValue()).toEqual({ - // a: 3, - // b: false, - // c: 'string', - // }); + const objAProp = formNode?.getProp('obj.a'); + const objBProp = formNode?.getProp('obj.b'); + const objCProp = formNode?.getProp('obj.c'); + expect(objAProp?.getValue()).toBe(3); + expect(objBProp?.getValue()).toBe(false); + expect(objCProp?.getValue()).toBe('string'); + expect(objProp?.getValue()).toEqual({ + a: 3, + b: false, + c: 'string', + }); }); it('修改普通属性,string | number | object,使用 Prop 实例接口', () => { @@ -296,11 +296,11 @@ describe('schema 生成节点模型测试', () => { expect(objAProp?.getValue()).toBe(3); expect(objBProp?.getValue()).toBe(false); expect(objCProp?.getValue()).toBe('string'); - // expect(objProp?.getValue()).toEqual({ - // a: 3, - // b: false, - // c: 'string', - // }); + expect(objProp?.getValue()).toEqual({ + a: 3, + b: false, + c: 'string', + }); }); }); diff --git a/packages/designer/tests/document/node/props/prop.test_wip.ts b/packages/designer/tests/document/node/props/prop.test.ts similarity index 100% rename from packages/designer/tests/document/node/props/prop.test_wip.ts rename to packages/designer/tests/document/node/props/prop.test.ts diff --git a/packages/designer/tests/document/node/props/props.test_wip.ts b/packages/designer/tests/document/node/props/props.test.ts similarity index 100% rename from packages/designer/tests/document/node/props/props.test_wip.ts rename to packages/designer/tests/document/node/props/props.test.ts diff --git a/packages/editor-skeleton/src/components/object-setter/index.tsx b/packages/editor-skeleton/src/components/object-setter/index.tsx index ec309ff2c..eb0bd6058 100644 --- a/packages/editor-skeleton/src/components/object-setter/index.tsx +++ b/packages/editor-skeleton/src/components/object-setter/index.tsx @@ -159,23 +159,32 @@ interface FormSetterProps { config: ObjectSetterConfig; } class FormSetter extends Component { - private items: SettingField[]; + private items: (SettingField | CustomView)[]; constructor(props: RowSetterProps) { super(props); const { config, field } = props; const { extraProps } = field; - field.items.forEach((item: SettingField | CustomView) => { - if (isSettingField(item)) { - const originalSetValue = item.extraProps.setValue; - item.extraProps.setValue = (...args) => { - // 调用子字段本身的 setValue - originalSetValue?.apply(null, args); - // 调用父字段本身的 setValue - extraProps.setValue?.apply(null, args); - }; - } - }); + + if (Array.isArray(field.items) && field.items.length > 0) { + field.items.forEach((item: SettingField | CustomView) => { + if (isSettingField(item)) { + const originalSetValue = item.extraProps.setValue; + item.extraProps.setValue = (...args) => { + // 调用子字段本身的 setValue + originalSetValue?.apply(null, args); + // 调用父字段本身的 setValue + extraProps.setValue?.apply(null, args); + }; + } + }); + this.items = field.items; + } else { + this.items = (config?.items || []).map((conf) => field.createField({ + ...conf, + setValue: extraProps?.setValue, + })); + } // TODO: extraConfig for custom fields } @@ -187,7 +196,7 @@ class FormSetter extends Component { const { field } = this.props; return (
- {field.items.map((item, index) => createSettingFieldView(item, field, index))} + {this.items.map((item, index) => createSettingFieldView(item, field, index))}
); } diff --git a/packages/editor-skeleton/src/components/settings/settings-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-pane.tsx index a003318b5..16f9ae138 100644 --- a/packages/editor-skeleton/src/components/settings/settings-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-pane.tsx @@ -24,7 +24,7 @@ class SettingFieldView extends Component<{ field: SettingField }> { const { field } = this.props; const { extraProps, componentMeta } = field; const { condition, defaultValue, display } = extraProps; - const { prototype } = componentMeta; + const { prototype } = componentMeta!; let visible; try { visible = typeof condition === 'function' ? condition(field) !== false : true;