Skip to content

Commit 1f9150e

Browse files
LeoYuanliujuping
authored andcommitted
feat: support SPA mode
1 parent 0bcd9ff commit 1f9150e

File tree

6 files changed

+38
-35
lines changed

6 files changed

+38
-35
lines changed

packages/designer/src/builtin-simulator/create-simulator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export function createSimulator(
9898
doc.close();
9999

100100
return new Promise((resolve) => {
101-
const renderer = win.SimulatorRenderer || host.renderer;
101+
const renderer = win.SimulatorRenderer;
102102
if (renderer) {
103103
return resolve(renderer);
104104
}

packages/designer/src/builtin-simulator/host.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
850850

851851
// filter with context
852852
return instances.filter((instance) => {
853-
return this.getClosestNodeInstance(instance, context.nodeId)?.instance === context.instance;
853+
return this.getClosestNodeInstance(instance, context?.nodeId)?.instance === context.instance;
854854
});
855855
}
856856

packages/engine/src/engine-core.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createElement } from 'react';
2-
import { render } from 'react-dom';
2+
import { render, unmountComponentAtNode } from 'react-dom';
33
import { globalContext, Editor, engineConfig, EngineOptions } from '@alilc/lowcode-editor-core';
44
import {
55
Designer,
@@ -16,7 +16,7 @@ import {
1616

1717
import Outline, { OutlineBackupPane, getTreeMaster } from '@alilc/lowcode-plugin-outline-pane';
1818
import DesignerPlugin from '@alilc/lowcode-plugin-designer';
19-
import { Hotkey, Project, Skeleton, Setters, Material, Event } from '@alilc/lowcode-shell';
19+
import { Hotkey, Project, Skeleton, Setters, Material, Event, DocumentModel } from '@alilc/lowcode-shell';
2020
import { getLogger, isPlainObject } from '@alilc/lowcode-utils';
2121
import './modules/live-editing';
2222
import utils from './modules/utils';
@@ -184,7 +184,8 @@ engineConfig.set('isOpenSource', isOpenSource);
184184
await plugins.register(defaultPanelRegistry);
185185
})();
186186

187-
let engineInited = false;
187+
// container which will host LowCodeEngine DOM
188+
let engineContainer: HTMLElement;
188189
// @ts-ignore webpack Define variable
189190
export const version = VERSION_PLACEHOLDER;
190191
engineConfig.set('ENGINE_VERSION', version);
@@ -193,23 +194,22 @@ export async function init(
193194
options?: EngineOptions,
194195
pluginPreference?: PluginPreference,
195196
) {
196-
if (engineInited) return;
197-
engineInited = true;
197+
await destroy();
198198
let engineOptions = null;
199-
let engineContainer = null;
200199
if (isPlainObject(container)) {
201200
engineOptions = container;
202201
engineContainer = document.createElement('div');
202+
engineContainer.id = 'engine';
203203
document.body.appendChild(engineContainer);
204204
} else {
205205
engineOptions = options;
206206
engineContainer = container;
207207
if (!container) {
208208
engineContainer = document.createElement('div');
209+
engineContainer.id = 'engine';
209210
document.body.appendChild(engineContainer);
210211
}
211212
}
212-
engineContainer.id = 'engine';
213213
engineConfig.setEngineOptions(engineOptions as any);
214214

215215
await plugins.init(pluginPreference as any);
@@ -222,3 +222,17 @@ export async function init(
222222
engineContainer,
223223
);
224224
}
225+
226+
export async function destroy() {
227+
// remove all documents
228+
const { documents } = project;
229+
if (Array.isArray(documents) && documents.length > 0) {
230+
documents.forEach(((doc: DocumentModel) => project.removeDocument(doc)));
231+
}
232+
233+
// TODO: delete plugins except for core plugins
234+
235+
// unmount DOM container, this will trigger React componentWillUnmount lifeCycle,
236+
// so necessary cleanups will be done.
237+
engineContainer && unmountComponentAtNode(engineContainer);
238+
}

packages/react-simulator-renderer/src/renderer-view.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { getClosestNode, isFromVC, isReactComponent } from '@alilc/lowcode-utils
88
import { GlobalEvent } from '@alilc/lowcode-types';
99
import { SimulatorRendererContainer, DocumentInstance } from './renderer';
1010
import { host } from './host';
11-
11+
import { isRendererDetached } from './utils/misc';
1212
import './renderer.less';
1313

1414
// patch cloneElement avoid lost keyProps
@@ -170,14 +170,12 @@ class Renderer extends Component<{
170170
this.startTime = Date.now();
171171
this.schemaChangedSymbol = false;
172172

173-
if (!container.autoRender) return null;
173+
if (!container.autoRender || isRendererDetached()) return null;
174174
return (
175175
<LowCodeRenderer
176176
locale={locale}
177177
messages={messages}
178178
schema={documentInstance.schema}
179-
deltaData={documentInstance.deltaData}
180-
deltaMode={documentInstance.deltaMode}
181179
components={container.components}
182180
appHelper={container.context}
183181
designMode={designMode}

packages/react-simulator-renderer/src/renderer.ts

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,6 @@ export class DocumentInstance {
5151
return this._components;
5252
}
5353

54-
/**
55-
* 本次的变更数据
56-
*/
57-
@obx.ref private _deltaData: any = {};
58-
59-
@computed get deltaData(): any {
60-
return this._deltaData;
61-
}
62-
63-
/**
64-
* 是否使用增量模式
65-
*/
66-
@obx.ref private _deltaMode: boolean = false;
67-
68-
@computed get deltaMode(): boolean {
69-
return this._deltaMode;
70-
}
71-
7254
// context from: utils、constants、history、location、match
7355
@obx.ref private _appContext = {};
7456

@@ -116,7 +98,7 @@ export class DocumentInstance {
11698
return this.document.id;
11799
}
118100

119-
private unmountIntance(id: string, instance: ReactInstance) {
101+
private unmountInstance(id: string, instance: ReactInstance) {
120102
const instances = this.instancesMap.get(id);
121103
if (instances) {
122104
const i = instances.indexOf(instance);
@@ -144,11 +126,11 @@ export class DocumentInstance {
144126
}
145127
return;
146128
}
147-
const unmountIntance = this.unmountIntance.bind(this);
129+
const unmountInstance = this.unmountInstance.bind(this);
148130
const origId = (instance as any)[SYMBOL_VNID];
149131
if (origId && origId !== id) {
150132
// 另外一个节点的 instance 在此被复用了,需要从原来地方卸载
151-
unmountIntance(origId, instance);
133+
unmountInstance(origId, instance);
152134
}
153135
if (isElement(instance)) {
154136
cacheReactKey(instance);
@@ -160,7 +142,7 @@ export class DocumentInstance {
160142
}
161143
// hack! delete instance from map
162144
const newUnmount = function (this: any) {
163-
unmountIntance(id, instance);
145+
unmountInstance(id, instance);
164146
origUnmount && origUnmount.call(this);
165147
};
166148
(newUnmount as any).origUnmount = origUnmount;

packages/react-simulator-renderer/src/utils/misc.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,12 @@ export function getProjectUtils(librayMap: LibrayMap, utilsMetadata: UtilsMetada
2424
});
2525
}
2626
}
27+
28+
/**
29+
* judges if current simulator renderer deteched or not
30+
* @returns detached or not
31+
*/
32+
export function isRendererDetached() {
33+
// if current iframe detached from host document, the `window.parent` will be undefined.
34+
return !window.parent;
35+
}

0 commit comments

Comments
 (0)