mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-13 01:21:58 +00:00
refactor(prop): 每次 prop.dispose 后需要重新构建 items, field.items 有则复用, 无则新建
This commit is contained in:
parent
f747f7934b
commit
51eaf4051c
@ -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;
|
||||
|
||||
@ -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',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -159,23 +159,32 @@ interface FormSetterProps {
|
||||
config: ObjectSetterConfig;
|
||||
}
|
||||
class FormSetter extends Component<FormSetterProps> {
|
||||
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<FormSetterProps> {
|
||||
const { field } = this.props;
|
||||
return (
|
||||
<div className="lc-setter-object lc-block-setter">
|
||||
{field.items.map((item, index) => createSettingFieldView(item, field, index))}
|
||||
{this.items.map((item, index) => createSettingFieldView(item, field, index))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user