mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-13 01:21:58 +00:00
refactor: 优化初始创建 doc 时触发响应式获取 schema 的次数
This commit is contained in:
parent
f4e07fe290
commit
3b645d270d
@ -6,7 +6,7 @@ module.exports = {
|
||||
// // '^.+\\.(ts|tsx)$': 'ts-jest',
|
||||
// // '^.+\\.(js|jsx)$': 'babel-jest',
|
||||
// },
|
||||
// testMatch: ['**/prop.test.ts'],
|
||||
// testMatch: ['**/builtin-hotkey.test.ts'],
|
||||
// testMatch: ['(/tests?/.*(test))\\.[jt]s$'],
|
||||
transformIgnorePatterns: [
|
||||
`/node_modules/(?!${esModules})/`,
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from 'events';
|
||||
import { autorun, Reaction, untracked, globalContext, Editor } from '@ali/lowcode-editor-core';
|
||||
import { autorun, reaction, mobx, untracked, globalContext, Editor } from '@ali/lowcode-editor-core';
|
||||
import { NodeSchema } from '@ali/lowcode-types';
|
||||
|
||||
// TODO: cache to localStorage
|
||||
@ -37,17 +37,12 @@ export class History {
|
||||
this.session = new Session(0, null, this.timeGap);
|
||||
this.records = [this.session];
|
||||
|
||||
autorun(() => {
|
||||
reaction(() => {
|
||||
return logger();
|
||||
}, (data) => {
|
||||
if (this.asleep) return;
|
||||
const data = logger();
|
||||
|
||||
untracked(() => {
|
||||
const log = currentSerialization.serialize(data);
|
||||
if (this.session.cursor === 0 && this.session.isActive()) {
|
||||
// first log
|
||||
this.session.log(log);
|
||||
this.session.end();
|
||||
} else if (this.session) {
|
||||
if (this.session.isActive()) {
|
||||
this.session.log(log);
|
||||
} else {
|
||||
@ -62,9 +57,9 @@ export class History {
|
||||
this.emitter.emit('statechange', currentState);
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
});
|
||||
});
|
||||
}, { fireImmediately: true });
|
||||
}
|
||||
|
||||
get hotData() {
|
||||
|
||||
@ -122,7 +122,7 @@ export class ModalNodesManager {
|
||||
}
|
||||
|
||||
private setNodes() {
|
||||
const nodes = getModalNodes(this.page.getRoot());
|
||||
const nodes = getModalNodes(this.page.getRoot()!);
|
||||
this.modalNodes = nodes;
|
||||
this.modalNodes.forEach((node: Node) => {
|
||||
this.addNodeEvent(node);
|
||||
|
||||
@ -179,6 +179,8 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
this.setupAutoruns();
|
||||
}
|
||||
|
||||
this.initBuiltinProps();
|
||||
|
||||
this.isInited = true;
|
||||
this.emitter = new EventEmitter();
|
||||
}
|
||||
@ -191,6 +193,18 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
return this._settingEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* 节点初始化期间就把内置的一些 prop 初始化好,避免后续不断构造实例导致 reaction 执行多次
|
||||
*/
|
||||
private initBuiltinProps() {
|
||||
this.props.has(getConvertedExtraKey('hidden')) || this.props.add(false, getConvertedExtraKey('hidden'));
|
||||
this.props.has(getConvertedExtraKey('title')) || this.props.add('', getConvertedExtraKey('title'));
|
||||
this.props.has(getConvertedExtraKey('isLocked')) || this.props.add(false, getConvertedExtraKey('isLocked'));
|
||||
this.props.has(getConvertedExtraKey('condition')) || this.props.add(true, getConvertedExtraKey('condition'));
|
||||
this.props.has(getConvertedExtraKey('conditionGroup')) || this.props.add('', getConvertedExtraKey('conditionGroup'));
|
||||
this.props.has(getConvertedExtraKey('loop')) || this.props.add(undefined, getConvertedExtraKey('loop'));
|
||||
}
|
||||
|
||||
private initProps(props: any): any {
|
||||
return this.document.designer.transformProps(props, this, TransformStage.Init);
|
||||
}
|
||||
|
||||
@ -102,6 +102,9 @@ describe('快捷键测试', () => {
|
||||
const firstButtonNode = designer.currentDocument?.getNode('node_k1ow3cbn')!;
|
||||
let secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||
|
||||
// 等待第一个 session 结束
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
firstButtonNode.remove();
|
||||
expect(secondButtonNode.getParent()?.children.size).toBe(1);
|
||||
|
||||
@ -119,6 +122,9 @@ describe('快捷键测试', () => {
|
||||
const firstButtonNode = designer.currentDocument?.getNode('node_k1ow3cbn')!;
|
||||
let secondButtonNode = designer.currentDocument?.getNode('node_k1ow3cbp')!;
|
||||
|
||||
// 等待第一个 session 结束
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
firstButtonNode.remove();
|
||||
expect(secondButtonNode.getParent()?.children.size).toBe(1);
|
||||
|
||||
|
||||
@ -68,7 +68,11 @@ Object {
|
||||
Object {
|
||||
"componentName": "PageHeader",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbd",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__slot__action": false,
|
||||
"__slot__content": false,
|
||||
@ -108,12 +112,18 @@ Object {
|
||||
],
|
||||
},
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "RootHeader",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cba",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"children": Array [
|
||||
@ -130,7 +140,11 @@ Object {
|
||||
Object {
|
||||
"componentName": "TextField",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbz",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__category__": "form",
|
||||
"__style__": Object {},
|
||||
@ -200,11 +214,16 @@ Object {
|
||||
"wrapperColOffset": 0,
|
||||
"wrapperColSpan": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"componentName": "TextField",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc1",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__category__": "form",
|
||||
"__style__": Object {},
|
||||
@ -270,11 +289,16 @@ Object {
|
||||
"wrapperColOffset": 0,
|
||||
"wrapperColSpan": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"componentName": "TextField",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc3",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__category__": "form",
|
||||
"__style__": Object {},
|
||||
@ -340,23 +364,33 @@ Object {
|
||||
"wrapperColOffset": 0,
|
||||
"wrapperColSpan": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "Column",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbx",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": Object {},
|
||||
"colSpan": "",
|
||||
"fieldId": "column_k1p1bnjm",
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"componentName": "TextField",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc2",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__category__": "form",
|
||||
"__style__": Object {},
|
||||
@ -422,11 +456,16 @@ Object {
|
||||
"wrapperColOffset": 0,
|
||||
"wrapperColSpan": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"componentName": "SelectField",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc0",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__category__": "form",
|
||||
"__style__": Object {},
|
||||
@ -512,21 +551,31 @@ Object {
|
||||
"wrapperColOffset": 0,
|
||||
"wrapperColSpan": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "Column",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cby",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": Object {},
|
||||
"colSpan": "",
|
||||
"fieldId": "column_k1p1bnjn",
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "ColumnsLayout",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbw",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": Object {},
|
||||
"columnGap": "20",
|
||||
@ -534,17 +583,27 @@ Object {
|
||||
"layout": "6:6",
|
||||
"rowGap": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "CardContent",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbk",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "Card",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbj",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__slot__extra": false,
|
||||
"__slot__subTitle": false,
|
||||
@ -576,6 +635,7 @@ Object {
|
||||
"zh_CN": "基本信息",
|
||||
},
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"children": Array [
|
||||
@ -584,7 +644,11 @@ Object {
|
||||
Object {
|
||||
"componentName": "TextField",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc4",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__category__": "form",
|
||||
"__style__": Object {},
|
||||
@ -650,6 +714,7 @@ Object {
|
||||
"wrapperColOffset": 0,
|
||||
"wrapperColSpan": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"children": Array [
|
||||
@ -658,7 +723,11 @@ Object {
|
||||
Object {
|
||||
"componentName": "TextField",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc8",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__category__": "form",
|
||||
"__style__": Object {},
|
||||
@ -724,23 +793,33 @@ Object {
|
||||
"wrapperColOffset": 0,
|
||||
"wrapperColSpan": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "Column",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc6",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": Object {},
|
||||
"colSpan": "",
|
||||
"fieldId": "column_k1p1bnjo",
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"componentName": "TextField",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc9",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__category__": "form",
|
||||
"__style__": Object {},
|
||||
@ -806,21 +885,31 @@ Object {
|
||||
"wrapperColOffset": 0,
|
||||
"wrapperColSpan": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "Column",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc7",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": Object {},
|
||||
"colSpan": "",
|
||||
"fieldId": "column_k1p1bnjp",
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "ColumnsLayout",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cc5",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": Object {},
|
||||
"columnGap": "20",
|
||||
@ -828,17 +917,27 @@ Object {
|
||||
"layout": "6:6",
|
||||
"rowGap": 0,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "CardContent",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbm",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "Card",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbl",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__slot__extra": false,
|
||||
"__slot__subTitle": false,
|
||||
@ -870,13 +969,18 @@ Object {
|
||||
"zh_CN": "部门信息",
|
||||
},
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"children": Array [
|
||||
Object {
|
||||
"componentName": "Button",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbn",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": ":root {
|
||||
margin-right: 16px;
|
||||
@ -912,11 +1016,16 @@ Object {
|
||||
"triggerEventsWhenLoading": false,
|
||||
"type": "primary",
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"componentName": "Button",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbp",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": ":root {
|
||||
width: 80px;
|
||||
@ -945,11 +1054,16 @@ Object {
|
||||
"triggerEventsWhenLoading": false,
|
||||
"type": "normal",
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "Div",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbo",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": ":root {
|
||||
display: flex;
|
||||
@ -965,12 +1079,17 @@ Object {
|
||||
"fieldId": "div_k1ow3h1o",
|
||||
"useFieldIdAsDomId": false,
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "Form",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"extraPropA": "extraPropA",
|
||||
"hidden": false,
|
||||
"id": "form",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"__style__": Object {},
|
||||
"autoUnmount": true,
|
||||
@ -992,26 +1111,38 @@ Object {
|
||||
"size": "medium",
|
||||
"slotA": "",
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "RootContent",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbb",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {
|
||||
"contentBgColor": "transparent",
|
||||
"contentMargin": "20",
|
||||
"contentPadding": "0",
|
||||
},
|
||||
"title": "",
|
||||
},
|
||||
Object {
|
||||
"componentName": "RootFooter",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"hidden": false,
|
||||
"id": "node_k1ow3cbc",
|
||||
"isLocked": false,
|
||||
"loop": undefined,
|
||||
"props": Object {},
|
||||
"title": "",
|
||||
},
|
||||
],
|
||||
"componentName": "Page",
|
||||
"condition": true,
|
||||
"conditionGroup": "",
|
||||
"css": "body{background-color:#f2f3f5}.card_kgaqfbm5 {
|
||||
margin-bottom: 12px;
|
||||
}.card_kgaqfbm6 {
|
||||
@ -1042,7 +1173,9 @@ Object {
|
||||
"online": Array [],
|
||||
"sync": true,
|
||||
},
|
||||
"hidden": false,
|
||||
"id": "page",
|
||||
"isLocked": false,
|
||||
"lifeCycles": Object {
|
||||
"constructor": Object {
|
||||
"compiled": "function constructor() {
|
||||
@ -1070,6 +1203,7 @@ Object.keys(module.exports).forEach(function(item) {
|
||||
"type": "js",
|
||||
},
|
||||
},
|
||||
"loop": undefined,
|
||||
"methods": Object {
|
||||
"__initMethods__": Object {
|
||||
"compiled": "function (exports, module) { /*set actions code here*/ }",
|
||||
|
||||
@ -32,6 +32,12 @@ describe('document-model 测试', () => {
|
||||
expect(doc.isBlank()).toBeFalsy();
|
||||
expect(doc.schema).toEqual({
|
||||
componentName: 'Page',
|
||||
condition: true,
|
||||
conditionGroup: '',
|
||||
hidden: false,
|
||||
isLocked: false,
|
||||
loop: undefined,
|
||||
title: '',
|
||||
id: 'root',
|
||||
fileName: '',
|
||||
props: {},
|
||||
|
||||
@ -249,7 +249,7 @@ describe('Node 方法测试', () => {
|
||||
|
||||
// getComponentName
|
||||
btnParent.insertAfter({ getComponentName: () => 'Button' }, firstBtn);
|
||||
expect(btnParent.children.get(1)?.getProps().export().props).toBeUndefined();
|
||||
expect(btnParent.children.get(1)?.getProps().export().props).toEqual({});
|
||||
expect(mockFn).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
});
|
||||
|
||||
@ -71,14 +71,14 @@ const pages = Object.assign(project, {
|
||||
componentsTree,
|
||||
id: pages[0].id,
|
||||
config: project.config,
|
||||
},
|
||||
},
|
||||
true,
|
||||
);
|
||||
// FIXME: 根本原因是 PropStash 导致的,在页面节点初始化结束后,hideModalNodes 导致了第一次变化
|
||||
// FIXME: 在页面节点初始化结束后,还有响应式变量变化导致了多次变化
|
||||
// 这样可以避免页面加载之后就被标记为 isModified
|
||||
setTimeout(() => {
|
||||
project.currentDocument?.history.savePoint();
|
||||
}, 0);
|
||||
}, 1000);
|
||||
},
|
||||
addPage(data: OldPageData | RootSchema) {
|
||||
if (isPageDataV1(data)) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user