From b4f8eed6295e358ba76a9c66319cba085cf1fdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8A=9B=E7=9A=93?= Date: Wed, 16 Jun 2021 12:54:53 +0800 Subject: [PATCH] =?UTF-8?q?refactor(prop):=20=E6=AF=8F=E6=AC=A1=20prop.dis?= =?UTF-8?q?pose=20=E5=90=8E=E9=9C=80=E8=A6=81=E9=87=8D=E6=96=B0=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=20items,=20field.items=20=E6=9C=89=E5=88=99=E5=A4=8D?= =?UTF-8?q?=E7=94=A8,=20=E6=97=A0=E5=88=99=E6=96=B0=E5=BB=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designer/src/document/node/props/prop.ts | 52 +-------------- .../tests/document/node/node.modify.test.ts | 66 +++++++++---------- .../props/{prop.test_wip.ts => prop.test.ts} | 0 .../{props.test_wip.ts => props.test.ts} | 0 .../src/components/object-setter/index.tsx | 35 ++++++---- .../src/components/settings/settings-pane.tsx | 2 +- 6 files changed, 58 insertions(+), 97 deletions(-) rename packages/designer/tests/document/node/props/{prop.test_wip.ts => prop.test.ts} (100%) rename packages/designer/tests/document/node/props/{props.test_wip.ts => props.test.ts} (100%) 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;