diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index a762daaea..d12427074 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -36,6 +36,7 @@ import { hasOwnProperty, UtilsMetadata, getClosestNode, + transactionManager, } from '@alilc/lowcode-utils'; import { DragObjectType, @@ -59,9 +60,8 @@ import { getClosestClickableNode } from './utils/clickable'; import { ComponentMetadata, ComponentSchema, - TransformStage, - ActivityData, Package, + TransitionType, } from '@alilc/lowcode-types'; import { BuiltinSimulatorRenderer } from './renderer'; import clipboard from '../designer/clipboard'; @@ -181,6 +181,14 @@ export class BuiltinSimulatorHost implements ISimulatorHost { + this.stopAutoRepaintNode(); + }, TransitionType.REPAINT); + transactionManager.onEndTransaction(() => { + this.rerender(); + this.enableAutoRepaintNode(); + }, TransitionType.REPAINT); } get currentDocument() { diff --git a/packages/designer/src/builtin-simulator/renderer.ts b/packages/designer/src/builtin-simulator/renderer.ts index 32c0e2567..a25f53200 100644 --- a/packages/designer/src/builtin-simulator/renderer.ts +++ b/packages/designer/src/builtin-simulator/renderer.ts @@ -13,6 +13,8 @@ export interface BuiltinSimulatorRenderer { setCopyState(state: boolean): void; loadAsyncLibrary(asyncMap: { [index: string]: any }): void; clearState(): void; + stopAutoRepaintNode(): void; + enableAutoRepaintNode(): void; run(): void; } diff --git a/packages/designer/src/document/history.ts b/packages/designer/src/document/history.ts index 5ac0d99cc..69f8662a7 100644 --- a/packages/designer/src/document/history.ts +++ b/packages/designer/src/document/history.ts @@ -1,5 +1,5 @@ import { EventEmitter } from 'events'; -import { autorun, reaction, mobx, untracked, globalContext, Editor } from '@alilc/lowcode-editor-core'; +import { reaction, untracked, globalContext, Editor } from '@alilc/lowcode-editor-core'; import { NodeSchema } from '@alilc/lowcode-types'; import { History as ShellHistory } from '@alilc/lowcode-shell'; @@ -32,31 +32,30 @@ export class History { this.currentSerialization = serialization; } - constructor(dataFn: () => T, private redoer: (data: T) => void, private timeGap: number = 1000) { + constructor(dataFn: () => T | null, private redoer: (data: T) => void, private timeGap: number = 1000) { this.session = new Session(0, null, this.timeGap); this.records = [this.session]; - reaction(() => { + reaction((): any => { return dataFn(); }, (data: T) => { if (this.asleep) return; untracked(() => { const log = this.currentSerialization.serialize(data); - if (this.session.isActive()) { - this.session.log(log); - } else { - this.session.end(); - const lastState = this.getState(); - const cursor = this.session.cursor + 1; - const session = new Session(cursor, log, this.timeGap); - this.session = session; - this.records.splice(cursor, this.records.length - cursor, session); - const currentState = this.getState(); - if (currentState !== lastState) { - this.emitter.emit('statechange', currentState); - } + if (this.session.isActive()) { + this.session.log(log); + } else { + this.session.end(); + const lastState = this.getState(); + const cursor = this.session.cursor + 1; + const session = new Session(cursor, log, this.timeGap); + this.session = session; + this.records.splice(cursor, this.records.length - cursor, session); + const currentState = this.getState(); + if (currentState !== lastState) { + this.emitter.emit('statechange', currentState); } - // } + } }); }, { fireImmediately: true }); } diff --git a/packages/engine/src/modules/utils.ts b/packages/engine/src/modules/utils.ts index 7e7cf6206..6d89e31e0 100644 --- a/packages/engine/src/modules/utils.ts +++ b/packages/engine/src/modules/utils.ts @@ -1,6 +1,6 @@ -import { isFormEvent, compatibleLegaoSchema, getNodeSchemaById } from '@alilc/lowcode-utils'; +import { isFormEvent, compatibleLegaoSchema, getNodeSchemaById, transactionManager } from '@alilc/lowcode-utils'; import { isNodeSchema } from '@alilc/lowcode-types'; -import { getConvertedExtraKey, getOriginalExtraKey, isNode, isSettingField } from '@alilc/lowcode-designer'; +import { getConvertedExtraKey, getOriginalExtraKey } from '@alilc/lowcode-designer'; const utils = { isNodeSchema, @@ -9,6 +9,7 @@ const utils = { getNodeSchemaById, getConvertedExtraKey, getOriginalExtraKey, + executeTransaction: transactionManager.executeTransaction.bind(transactionManager), }; export default utils; \ No newline at end of file diff --git a/packages/react-simulator-renderer/src/renderer.ts b/packages/react-simulator-renderer/src/renderer.ts index 2dfdeccac..98cbbd621 100644 --- a/packages/react-simulator-renderer/src/renderer.ts +++ b/packages/react-simulator-renderer/src/renderer.ts @@ -349,6 +349,11 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer { * 是否为画布自动渲染 */ autoRender = true; + + /** + * 画布是否自动监听事件来重绘节点 + */ + autoRepaintNode = true; /** * 加载资源 */ @@ -491,6 +496,14 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer { this._appContext = { ...this._appContext }; } + stopAutoRepaintNode() { + this.autoRepaintNode = false; + } + + enableAutoRepaintNode() { + this.autoRepaintNode = true; + } + dispose() { this.disposeFunctions.forEach(fn => fn()); this.documentInstances.forEach(docInst => docInst.dispose()); diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index e2dbd22d4..fb5eb5293 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -102,14 +102,23 @@ function initRerenderEvent({ leaf, dispose: [ leaf?.onPropChange?.(() => { + if (!container.autoRepaintNode) { + return; + } __debug(`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onPropsChange make rerender`); container.rerender(); }), leaf?.onChildrenChange?.(() => { + if (!container.autoRepaintNode) { + return; + } __debug(`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onChildrenChange make rerender`); container.rerender(); }) as Function, leaf?.onVisibleChange?.(() => { + if (!container.autoRepaintNode) { + return; + } __debug(`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onVisibleChange make rerender`); container.rerender(); }), @@ -213,14 +222,18 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { } componentDidMount() { + const _leaf = this.leaf; + this.initOnPropsChangeEvent(_leaf); + this.initOnChildrenChangeEvent(_leaf); + this.initOnVisibleChangeEvent(_leaf); this.recordTime(); } - get defaultState() { + getDefaultState(nextProps: any) { const { hidden = false, condition = true, - } = this.leaf?.export?.(TransformStage.Render) || {}; + } = nextProps.__inner__ || this.leaf?.export?.(TransformStage.Render) || {}; return { nodeChildren: null, childrenInState: false, @@ -236,11 +249,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { // 监听以下事件,当变化时更新自己 __debug(`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`); clearRerenderEvent(componentCacheId); - const _leaf = this.leaf; - this.initOnPropsChangeEvent(_leaf); - this.initOnChildrenChangeEvent(_leaf); - this.initOnVisibleChangeEvent(_leaf); - this.curEventLeaf = _leaf; + this.curEventLeaf = this.leaf; cache.ref.set(componentCacheId, { makeUnitRender: this.makeUnitRender, @@ -248,7 +257,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { let cacheState = cache.state.get(componentCacheId); if (!cacheState || cacheState.__tag !== props.__tag) { - cacheState = this.defaultState; + cacheState = this.getDefaultState(props); } this.state = cacheState; @@ -279,6 +288,10 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { singleRender?: boolean; }; + get autoRepaintNode() { + return container.autoRepaintNode; + } + judgeMiniUnitRender() { if (!this.renderUnitInfo) { this.getRenderUnitInfo(); @@ -380,13 +393,16 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { const { visible, ...resetState - } = this.defaultState; + } = this.getDefaultState(nextProps); this.setState(resetState); } /** 监听参数变化 */ initOnPropsChangeEvent(leaf = this.leaf): void { - const dispose = leaf?.onPropChange?.(debounce((propChangeInfo: PropChangeOptions) => { + const dispose = leaf?.onPropChange?.((propChangeInfo: PropChangeOptions) => { + if (!this.autoRepaintNode) { + return; + } const { key, newValue = null, @@ -433,7 +449,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { }); this.judgeMiniUnitRender(); - }, 30)); + }); dispose && this.disposeFunctions.push(dispose); } @@ -443,6 +459,9 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { */ initOnVisibleChangeEvent(leaf = this.leaf) { const dispose = leaf?.onVisibleChange?.((flag: boolean) => { + if (!this.autoRepaintNode) { + return; + } if (this.state.visible === flag) { return; } @@ -463,6 +482,9 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { */ initOnChildrenChangeEvent(leaf = this.leaf) { const dispose = leaf?.onChildrenChange?.((param): void => { + if (!this.autoRepaintNode) { + return; + } const { type, node, @@ -540,6 +562,8 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { ref: forwardedRef, }; + delete compProps.__inner__; + return engine.createElement(Comp, compProps, this.hasChildren ? this.children : null); } } diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 2d58cac76..d64ff4196 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -670,7 +670,14 @@ export default function baseRendererFactory(): IBaseRenderComponent { } } } - return renderComp({ ...props, ...otherProps }); + return renderComp({ + ...props, + ...otherProps, + __inner__: { + hidden: schema.hidden, + condition, + }, + }); } catch (e) { return engine.createElement(engine.getFaultComponent(), { error: e, diff --git a/packages/renderer-core/tests/hoc/leaf.test.tsx b/packages/renderer-core/tests/hoc/leaf.test.tsx index 0e594bc5a..86675c771 100644 --- a/packages/renderer-core/tests/hoc/leaf.test.tsx +++ b/packages/renderer-core/tests/hoc/leaf.test.tsx @@ -35,7 +35,8 @@ const baseRenderer: any = { __container: { rerender: () => { rerenderCount = 1 + rerenderCount; - } + }, + autoRepaintNode: true, }, documentId: '01' }, diff --git a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap index 169ed545c..79c5f0f08 100644 --- a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap +++ b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap @@ -11,6 +11,12 @@ exports[`Base Render renderComp 1`] = ` >