Skip to content

Commit 71f9e08

Browse files
liujupingJackLian
authored andcommitted
fix: remove console.log statements, update test, and purge children in NodeChildren class
1 parent d7dfde5 commit 71f9e08

File tree

9 files changed

+77
-105
lines changed

9 files changed

+77
-105
lines changed

packages/designer/jest.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const jestConfig = {
2222
// testMatch: ['**/selection.test.ts'],
2323
// testMatch: ['**/plugin/sequencify.test.ts'],
2424
// testMatch: ['**/builtin-simulator/utils/parse-metadata.test.ts'],
25+
// testMatch: ['**/setting/setting-top-entry.test.ts'],
2526
transformIgnorePatterns: [
2627
`/node_modules/(?!${esModules})/`,
2728
],

packages/designer/src/designer/setting/setting-field.ts

+3-51
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { ReactNode } from 'react';
21
import {
32
IPublicTypeTitleContent,
43
IPublicTypeSetterType,
@@ -7,18 +6,15 @@ import {
76
IPublicTypeFieldConfig,
87
IPublicTypeCustomView,
98
IPublicTypeDisposable,
10-
IPublicModelSettingField,
11-
IBaseModelSettingField,
129
} from '@alilc/lowcode-types';
1310
import type {
1411
IPublicTypeSetValueOptions,
1512
} from '@alilc/lowcode-types';
1613
import { Transducer } from './utils';
17-
import { ISettingPropEntry, SettingPropEntry } from './setting-prop-entry';
14+
import { SettingPropEntry } from './setting-prop-entry';
1815
import { computed, obx, makeObservable, action, untracked, intl } from '@alilc/lowcode-editor-core';
1916
import { cloneDeep, isCustomView, isDynamicSetter, isJSExpression } from '@alilc/lowcode-utils';
2017
import { ISettingTopEntry } from './setting-top-entry';
21-
import { IComponentMeta, INode } from '@alilc/lowcode-designer';
2218

2319
function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, config: IPublicTypeFieldConfig) {
2420
let cur = parent;
@@ -32,53 +28,9 @@ function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, c
3228
return path.join('.');
3329
}
3430

35-
export interface ISettingField extends ISettingPropEntry, Omit<IBaseModelSettingField<
36-
ISettingTopEntry,
37-
ISettingField,
38-
IComponentMeta,
39-
INode
40-
>, 'setValue' | 'key' | 'node'> {
41-
readonly isSettingField: true;
31+
export interface ISettingField extends SettingField {}
4232

43-
readonly isRequired: boolean;
44-
45-
readonly isGroup: boolean;
46-
47-
extraProps: IPublicTypeFieldExtraProps;
48-
49-
get items(): Array<ISettingField | IPublicTypeCustomView>;
50-
51-
get title(): string | ReactNode | undefined;
52-
53-
get setter(): IPublicTypeSetterType | null;
54-
55-
get expanded(): boolean;
56-
57-
get valueState(): number;
58-
59-
setExpanded(value: boolean): void;
60-
61-
purge(): void;
62-
63-
setValue(
64-
val: any,
65-
isHotValue?: boolean,
66-
force?: boolean,
67-
extraOptions?: IPublicTypeSetValueOptions,
68-
): void;
69-
70-
clearValue(): void;
71-
72-
valueChange(options: IPublicTypeSetValueOptions): void;
73-
74-
createField(config: IPublicTypeFieldConfig): ISettingField;
75-
76-
onEffect(action: () => void): IPublicTypeDisposable;
77-
78-
internalToShellField(): IPublicModelSettingField;
79-
}
80-
81-
export class SettingField extends SettingPropEntry implements ISettingField {
33+
export class SettingField extends SettingPropEntry {
8234
readonly isSettingField = true;
8335

8436
readonly isRequired: boolean;

packages/designer/src/designer/setting/setting-top-entry.ts

+24-32
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry, IPublicApiSetters } from '@alilc/lowcode-types';
22
import { isCustomView } from '@alilc/lowcode-utils';
3-
import { computed, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
3+
import { computed, IEventBus, createModuleEventBus, obx, makeObservable } from '@alilc/lowcode-editor-core';
44
import { ISettingEntry } from './setting-entry-type';
55
import { ISettingField, SettingField } from './setting-field';
66
import { INode } from '../../document';
@@ -14,33 +14,17 @@ function generateSessionId(nodes: INode[]) {
1414
.join(',');
1515
}
1616

17-
export interface ISettingTopEntry extends ISettingEntry, IPublicModelSettingTopEntry<
17+
export interface ISettingTopEntry extends SettingTopEntry {}
18+
19+
export class SettingTopEntry implements ISettingEntry, IPublicModelSettingTopEntry<
1820
INode,
1921
ISettingField
2022
> {
21-
readonly top: ISettingTopEntry;
22-
23-
readonly parent: ISettingTopEntry;
24-
25-
readonly path: never[];
26-
27-
items: Array<ISettingField | IPublicTypeCustomView>;
28-
29-
componentMeta: IComponentMeta | null;
30-
31-
purge(): void;
32-
33-
getExtraPropValue(propName: string): void;
34-
35-
setExtraPropValue(propName: string, value: any): void;
36-
}
37-
38-
export class SettingTopEntry implements ISettingTopEntry {
3923
private emitter: IEventBus = createModuleEventBus('SettingTopEntry');
4024

41-
private _items: Array<SettingField | IPublicTypeCustomView> = [];
25+
private _items: Array<ISettingField | IPublicTypeCustomView> = [];
4226

43-
private _componentMeta: IComponentMeta | null = null;
27+
private _componentMeta: IComponentMeta | null | undefined = null;
4428

4529
private _isSame = true;
4630

@@ -75,7 +59,7 @@ export class SettingTopEntry implements ISettingTopEntry {
7559
}
7660

7761
get isLocked(): boolean {
78-
return this.first.isLocked;
62+
return this.first?.isLocked ?? false;
7963
}
8064

8165
/**
@@ -87,7 +71,11 @@ export class SettingTopEntry implements ISettingTopEntry {
8771

8872
readonly id: string;
8973

90-
readonly first: INode;
74+
@computed get first(): INode | null {
75+
return this._first;
76+
}
77+
78+
@obx.ref _first: INode | null;
9179

9280
readonly designer: IDesigner | undefined;
9381

@@ -96,12 +84,14 @@ export class SettingTopEntry implements ISettingTopEntry {
9684
disposeFunctions: any[] = [];
9785

9886
constructor(readonly editor: IPublicModelEditor, readonly nodes: INode[]) {
87+
makeObservable(this);
88+
9989
if (!Array.isArray(nodes) || nodes.length < 1) {
10090
throw new ReferenceError('nodes should not be empty');
10191
}
10292
this.id = generateSessionId(nodes);
103-
this.first = nodes[0];
104-
this.designer = this.first.document?.designer;
93+
this._first = nodes[0];
94+
this.designer = this._first.document?.designer;
10595
this.setters = editor.get('setters') as IPublicApiSetters;
10696

10797
// setups
@@ -116,7 +106,7 @@ export class SettingTopEntry implements ISettingTopEntry {
116106
private setupComponentMeta() {
117107
// todo: enhance compile a temp configure.compiled
118108
const { first } = this;
119-
const meta = first.componentMeta;
109+
const meta = first?.componentMeta;
120110
const l = this.nodes.length;
121111
let theSame = true;
122112
for (let i = 1; i < l; i++) {
@@ -160,7 +150,7 @@ export class SettingTopEntry implements ISettingTopEntry {
160150
/**
161151
* 获取当前属性值
162152
*/
163-
@computed getValue(): any {
153+
getValue(): any {
164154
return this.first?.propsData;
165155
}
166156

@@ -202,14 +192,14 @@ export class SettingTopEntry implements ISettingTopEntry {
202192
* 获取子级属性值
203193
*/
204194
getPropValue(propName: string | number): any {
205-
return this.first.getProp(propName.toString(), true)?.getValue();
195+
return this.first?.getProp(propName.toString(), true)?.getValue();
206196
}
207197

208198
/**
209199
* 获取顶层附属属性值
210200
*/
211201
getExtraPropValue(propName: string) {
212-
return this.first.getExtraProp(propName, false)?.getValue();
202+
return this.first?.getExtraProp(propName, false)?.getValue();
213203
}
214204

215205
/**
@@ -244,8 +234,9 @@ export class SettingTopEntry implements ISettingTopEntry {
244234
this.disposeItems();
245235
this._settingFieldMap = {};
246236
this.emitter.removeAllListeners();
247-
this.disposeFunctions.forEach(f => f());
237+
this.disposeFunctions.forEach(f => f?.());
248238
this.disposeFunctions = [];
239+
this._first = null;
249240
}
250241

251242
getProp(propName: string | number) {
@@ -274,7 +265,7 @@ export class SettingTopEntry implements ISettingTopEntry {
274265
}
275266

276267
getPage() {
277-
return this.first.document;
268+
return this.first?.document;
278269
}
279270

280271
/**
@@ -292,6 +283,7 @@ export class SettingTopEntry implements ISettingTopEntry {
292283
interface Purgeable {
293284
purge(): void;
294285
}
286+
295287
function isPurgeable(obj: any): obj is Purgeable {
296288
return obj && obj.purge;
297289
}

packages/designer/src/document/node/node-children.ts

+5
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,18 @@ export class NodeChildren implements Omit<IPublicModelNodeChildren<INode>,
9191
node.import(item);
9292
} else {
9393
node = this.owner.document?.createNode(item);
94+
child?.purge();
9495
}
9596

9697
if (node) {
9798
children[i] = node;
9899
}
99100
}
100101

102+
for (let i = data.length; i < originChildren.length; i++) {
103+
originChildren[i].purge();
104+
}
105+
101106
this.children = children;
102107
this.internalInitParent();
103108
if (!shallowEqual(children, originChildren)) {

packages/designer/src/document/node/node.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
987987
this.autoruns?.forEach((dispose) => dispose());
988988
this.props.purge();
989989
this.settingEntry?.purge();
990-
// this.document.destroyNode(this);
990+
this.children?.purge();
991991
}
992992

993993
internalPurgeStart() {

packages/designer/tests/designer/setting/setting-top-entry.test.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import '../../fixtures/window';
2-
import { Editor, Setters } from '@alilc/lowcode-editor-core';
2+
import { Editor, Setters, reaction } from '@alilc/lowcode-editor-core';
33
import { Node } from '../../../src/document/node/node';
44
import { Designer } from '../../../src/designer/designer';
55
import settingSchema from '../../fixtures/schema/setting';
6+
import { SettingTopEntry } from '../../../src/designer/setting/setting-top-entry';
67
import divMeta from '../../fixtures/component-metadata/div';
78
import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory';
89

@@ -109,6 +110,26 @@ describe('setting-top-entry 测试', () => {
109110
expect(settingEntry.items).toHaveLength(0);
110111
});
111112

113+
it('should notify when _first is set to null', (done) => {
114+
// 创建一个简单的INode数组用于初始化SettingTopEntry实例
115+
const nodes = [{ id: '1', propsData: {} }, { id: '2', propsData: {} }];
116+
const entry = new SettingTopEntry(editor as any, nodes as any);
117+
118+
// 使用MobX的reaction来观察_first属性的变化
119+
const dispose = reaction(
120+
() => entry.first,
121+
(first) => {
122+
if (first === null) {
123+
dispose(); // 清理reaction监听
124+
done(); // 结束测试
125+
}
126+
}
127+
);
128+
129+
// 执行purge方法,期望_first被设置为null,触发reaction回调
130+
entry.purge();
131+
});
132+
112133
it('vision 兼容测试', () => {
113134
designer.createComponentMeta(divMeta);
114135
designer.project.open(settingSchema);

packages/editor-core/src/hotkey.ts

-2
Original file line numberDiff line numberDiff line change
@@ -541,8 +541,6 @@ export class Hotkey implements Omit<IPublicApiHotkey, 'bind' | 'callbacks'> {
541541
}
542542

543543
private handleKeyEvent(e: KeyboardEvent): void {
544-
console.log(e);
545-
// debugger;
546544
if (!this.isActivate) {
547545
return;
548546
}

packages/editor-skeleton/src/components/settings/main.ts

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { Node, Designer, Selection, SettingTopEntry } from '@alilc/lowcode-designer';
1+
import { INode, IDesigner, Selection, SettingTopEntry } from '@alilc/lowcode-designer';
22
import { Editor, obx, computed, makeObservable, action, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
33

4-
function generateSessionId(nodes: Node[]) {
4+
function generateSessionId(nodes: INode[]) {
55
return nodes
66
.map((node) => node.id)
77
.sort()
@@ -29,7 +29,11 @@ export class SettingsMain {
2929

3030
private disposeListener: () => void;
3131

32-
private designer?: Designer;
32+
private _designer?: IDesigner;
33+
34+
get designer(): IDesigner | undefined {
35+
return this._designer;
36+
}
3337

3438
constructor(readonly editor: Editor) {
3539
makeObservable(this);
@@ -49,12 +53,12 @@ export class SettingsMain {
4953
this.editor.removeListener('designer.selection.change', setupSelection);
5054
};
5155
const designer = await this.editor.onceGot('designer');
52-
this.designer = designer;
56+
this._designer = designer;
5357
setupSelection(designer.currentSelection);
5458
}
5559

5660
@action
57-
private setup(nodes: Node[]) {
61+
private setup(nodes: INode[]) {
5862
// check nodes change
5963
const sessionId = generateSessionId(nodes);
6064
if (sessionId === this._sessionId) {
@@ -66,15 +70,15 @@ export class SettingsMain {
6670
return;
6771
}
6872

69-
if (!this.designer) {
70-
this.designer = nodes[0].document.designer;
73+
if (!this._designer) {
74+
this._designer = nodes[0].document.designer;
7175
}
7276
// 当节点只有一个时,复用 node 上挂载的 settingEntry,不会产生平行的两个实例,这样在整个系统中对
7377
// 某个节点操作的 SettingTopEntry 只有一个实例,后续的 getProp() 也会拿到相同的 SettingField 实例
7478
if (nodes.length === 1) {
7579
this._settings = nodes[0].settingEntry;
7680
} else {
77-
this._settings = this.designer.createSettingEntry(nodes);
81+
this._settings = this._designer.createSettingEntry(nodes);
7882
}
7983
}
8084

0 commit comments

Comments
 (0)