mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-14 13:03:07 +00:00
feat: support SPA mode
This commit is contained in:
parent
0bcd9ff782
commit
1f9150e4b2
@ -98,7 +98,7 @@ export function createSimulator(
|
||||
doc.close();
|
||||
|
||||
return new Promise((resolve) => {
|
||||
const renderer = win.SimulatorRenderer || host.renderer;
|
||||
const renderer = win.SimulatorRenderer;
|
||||
if (renderer) {
|
||||
return resolve(renderer);
|
||||
}
|
||||
|
||||
@ -850,7 +850,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
|
||||
// filter with context
|
||||
return instances.filter((instance) => {
|
||||
return this.getClosestNodeInstance(instance, context.nodeId)?.instance === context.instance;
|
||||
return this.getClosestNodeInstance(instance, context?.nodeId)?.instance === context.instance;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { createElement } from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { globalContext, Editor, engineConfig, EngineOptions } from '@alilc/lowcode-editor-core';
|
||||
import {
|
||||
Designer,
|
||||
@ -16,7 +16,7 @@ import {
|
||||
|
||||
import Outline, { OutlineBackupPane, getTreeMaster } from '@alilc/lowcode-plugin-outline-pane';
|
||||
import DesignerPlugin from '@alilc/lowcode-plugin-designer';
|
||||
import { Hotkey, Project, Skeleton, Setters, Material, Event } from '@alilc/lowcode-shell';
|
||||
import { Hotkey, Project, Skeleton, Setters, Material, Event, DocumentModel } from '@alilc/lowcode-shell';
|
||||
import { getLogger, isPlainObject } from '@alilc/lowcode-utils';
|
||||
import './modules/live-editing';
|
||||
import utils from './modules/utils';
|
||||
@ -184,7 +184,8 @@ engineConfig.set('isOpenSource', isOpenSource);
|
||||
await plugins.register(defaultPanelRegistry);
|
||||
})();
|
||||
|
||||
let engineInited = false;
|
||||
// container which will host LowCodeEngine DOM
|
||||
let engineContainer: HTMLElement;
|
||||
// @ts-ignore webpack Define variable
|
||||
export const version = VERSION_PLACEHOLDER;
|
||||
engineConfig.set('ENGINE_VERSION', version);
|
||||
@ -193,23 +194,22 @@ export async function init(
|
||||
options?: EngineOptions,
|
||||
pluginPreference?: PluginPreference,
|
||||
) {
|
||||
if (engineInited) return;
|
||||
engineInited = true;
|
||||
await destroy();
|
||||
let engineOptions = null;
|
||||
let engineContainer = null;
|
||||
if (isPlainObject(container)) {
|
||||
engineOptions = container;
|
||||
engineContainer = document.createElement('div');
|
||||
engineContainer.id = 'engine';
|
||||
document.body.appendChild(engineContainer);
|
||||
} else {
|
||||
engineOptions = options;
|
||||
engineContainer = container;
|
||||
if (!container) {
|
||||
engineContainer = document.createElement('div');
|
||||
engineContainer.id = 'engine';
|
||||
document.body.appendChild(engineContainer);
|
||||
}
|
||||
}
|
||||
engineContainer.id = 'engine';
|
||||
engineConfig.setEngineOptions(engineOptions as any);
|
||||
|
||||
await plugins.init(pluginPreference as any);
|
||||
@ -222,3 +222,17 @@ export async function init(
|
||||
engineContainer,
|
||||
);
|
||||
}
|
||||
|
||||
export async function destroy() {
|
||||
// remove all documents
|
||||
const { documents } = project;
|
||||
if (Array.isArray(documents) && documents.length > 0) {
|
||||
documents.forEach(((doc: DocumentModel) => project.removeDocument(doc)));
|
||||
}
|
||||
|
||||
// TODO: delete plugins except for core plugins
|
||||
|
||||
// unmount DOM container, this will trigger React componentWillUnmount lifeCycle,
|
||||
// so necessary cleanups will be done.
|
||||
engineContainer && unmountComponentAtNode(engineContainer);
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import { getClosestNode, isFromVC, isReactComponent } from '@alilc/lowcode-utils
|
||||
import { GlobalEvent } from '@alilc/lowcode-types';
|
||||
import { SimulatorRendererContainer, DocumentInstance } from './renderer';
|
||||
import { host } from './host';
|
||||
|
||||
import { isRendererDetached } from './utils/misc';
|
||||
import './renderer.less';
|
||||
|
||||
// patch cloneElement avoid lost keyProps
|
||||
@ -170,14 +170,12 @@ class Renderer extends Component<{
|
||||
this.startTime = Date.now();
|
||||
this.schemaChangedSymbol = false;
|
||||
|
||||
if (!container.autoRender) return null;
|
||||
if (!container.autoRender || isRendererDetached()) return null;
|
||||
return (
|
||||
<LowCodeRenderer
|
||||
locale={locale}
|
||||
messages={messages}
|
||||
schema={documentInstance.schema}
|
||||
deltaData={documentInstance.deltaData}
|
||||
deltaMode={documentInstance.deltaMode}
|
||||
components={container.components}
|
||||
appHelper={container.context}
|
||||
designMode={designMode}
|
||||
|
||||
@ -51,24 +51,6 @@ export class DocumentInstance {
|
||||
return this._components;
|
||||
}
|
||||
|
||||
/**
|
||||
* 本次的变更数据
|
||||
*/
|
||||
@obx.ref private _deltaData: any = {};
|
||||
|
||||
@computed get deltaData(): any {
|
||||
return this._deltaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否使用增量模式
|
||||
*/
|
||||
@obx.ref private _deltaMode: boolean = false;
|
||||
|
||||
@computed get deltaMode(): boolean {
|
||||
return this._deltaMode;
|
||||
}
|
||||
|
||||
// context from: utils、constants、history、location、match
|
||||
@obx.ref private _appContext = {};
|
||||
|
||||
@ -116,7 +98,7 @@ export class DocumentInstance {
|
||||
return this.document.id;
|
||||
}
|
||||
|
||||
private unmountIntance(id: string, instance: ReactInstance) {
|
||||
private unmountInstance(id: string, instance: ReactInstance) {
|
||||
const instances = this.instancesMap.get(id);
|
||||
if (instances) {
|
||||
const i = instances.indexOf(instance);
|
||||
@ -144,11 +126,11 @@ export class DocumentInstance {
|
||||
}
|
||||
return;
|
||||
}
|
||||
const unmountIntance = this.unmountIntance.bind(this);
|
||||
const unmountInstance = this.unmountInstance.bind(this);
|
||||
const origId = (instance as any)[SYMBOL_VNID];
|
||||
if (origId && origId !== id) {
|
||||
// 另外一个节点的 instance 在此被复用了,需要从原来地方卸载
|
||||
unmountIntance(origId, instance);
|
||||
unmountInstance(origId, instance);
|
||||
}
|
||||
if (isElement(instance)) {
|
||||
cacheReactKey(instance);
|
||||
@ -160,7 +142,7 @@ export class DocumentInstance {
|
||||
}
|
||||
// hack! delete instance from map
|
||||
const newUnmount = function (this: any) {
|
||||
unmountIntance(id, instance);
|
||||
unmountInstance(id, instance);
|
||||
origUnmount && origUnmount.call(this);
|
||||
};
|
||||
(newUnmount as any).origUnmount = origUnmount;
|
||||
|
||||
@ -24,3 +24,12 @@ export function getProjectUtils(librayMap: LibrayMap, utilsMetadata: UtilsMetada
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* judges if current simulator renderer deteched or not
|
||||
* @returns detached or not
|
||||
*/
|
||||
export function isRendererDetached() {
|
||||
// if current iframe detached from host document, the `window.parent` will be undefined.
|
||||
return !window.parent;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user