Skip to content

Commit e818d84

Browse files
liujupingLeoYuan
authored andcommitted
feat: add common.utils.executeTransaction API to change multi nodes
1 parent 9a0fd15 commit e818d84

File tree

14 files changed

+372
-34
lines changed

14 files changed

+372
-34
lines changed

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
hasOwnProperty,
3737
UtilsMetadata,
3838
getClosestNode,
39+
transactionManager,
3940
} from '@alilc/lowcode-utils';
4041
import {
4142
DragObjectType,
@@ -59,9 +60,8 @@ import { getClosestClickableNode } from './utils/clickable';
5960
import {
6061
ComponentMetadata,
6162
ComponentSchema,
62-
TransformStage,
63-
ActivityData,
6463
Package,
64+
TransitionType,
6565
} from '@alilc/lowcode-types';
6666
import { BuiltinSimulatorRenderer } from './renderer';
6767
import clipboard from '../designer/clipboard';
@@ -181,6 +181,14 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
181181
*/
182182
autoRender = true;
183183

184+
stopAutoRepaintNode() {
185+
this.renderer?.stopAutoRepaintNode();
186+
}
187+
188+
enableAutoRepaintNode() {
189+
this.renderer?.enableAutoRepaintNode();
190+
}
191+
184192
constructor(project: Project) {
185193
makeObservable(this);
186194
this.project = project;
@@ -194,6 +202,13 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
194202
i18n: this.project.i18n,
195203
};
196204
});
205+
transactionManager.onStartTransaction(() => {
206+
this.stopAutoRepaintNode();
207+
}, TransitionType.REPAINT);
208+
transactionManager.onEndTransaction(() => {
209+
this.rerender();
210+
this.enableAutoRepaintNode();
211+
}, TransitionType.REPAINT);
197212
}
198213

199214
get currentDocument() {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export interface BuiltinSimulatorRenderer {
1313
setCopyState(state: boolean): void;
1414
loadAsyncLibrary(asyncMap: { [index: string]: any }): void;
1515
clearState(): void;
16+
stopAutoRepaintNode(): void;
17+
enableAutoRepaintNode(): void;
1618
run(): void;
1719
}
1820

packages/designer/src/document/history.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { EventEmitter } from 'events';
2-
import { autorun, reaction, mobx, untracked, globalContext, Editor } from '@alilc/lowcode-editor-core';
2+
import { reaction, untracked, globalContext, Editor } from '@alilc/lowcode-editor-core';
33
import { NodeSchema } from '@alilc/lowcode-types';
44
import { History as ShellHistory } from '@alilc/lowcode-shell';
55

@@ -32,31 +32,30 @@ export class History<T = NodeSchema> {
3232
this.currentSerialization = serialization;
3333
}
3434

35-
constructor(dataFn: () => T, private redoer: (data: T) => void, private timeGap: number = 1000) {
35+
constructor(dataFn: () => T | null, private redoer: (data: T) => void, private timeGap: number = 1000) {
3636
this.session = new Session(0, null, this.timeGap);
3737
this.records = [this.session];
3838

39-
reaction(() => {
39+
reaction((): any => {
4040
return dataFn();
4141
}, (data: T) => {
4242
if (this.asleep) return;
4343
untracked(() => {
4444
const log = this.currentSerialization.serialize(data);
45-
if (this.session.isActive()) {
46-
this.session.log(log);
47-
} else {
48-
this.session.end();
49-
const lastState = this.getState();
50-
const cursor = this.session.cursor + 1;
51-
const session = new Session(cursor, log, this.timeGap);
52-
this.session = session;
53-
this.records.splice(cursor, this.records.length - cursor, session);
54-
const currentState = this.getState();
55-
if (currentState !== lastState) {
56-
this.emitter.emit('statechange', currentState);
57-
}
45+
if (this.session.isActive()) {
46+
this.session.log(log);
47+
} else {
48+
this.session.end();
49+
const lastState = this.getState();
50+
const cursor = this.session.cursor + 1;
51+
const session = new Session(cursor, log, this.timeGap);
52+
this.session = session;
53+
this.records.splice(cursor, this.records.length - cursor, session);
54+
const currentState = this.getState();
55+
if (currentState !== lastState) {
56+
this.emitter.emit('statechange', currentState);
5857
}
59-
// }
58+
}
6059
});
6160
}, { fireImmediately: true });
6261
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { isFormEvent, compatibleLegaoSchema, getNodeSchemaById } from '@alilc/lowcode-utils';
1+
import { isFormEvent, compatibleLegaoSchema, getNodeSchemaById, transactionManager } from '@alilc/lowcode-utils';
22
import { isNodeSchema } from '@alilc/lowcode-types';
3-
import { getConvertedExtraKey, getOriginalExtraKey, isNode, isSettingField } from '@alilc/lowcode-designer';
3+
import { getConvertedExtraKey, getOriginalExtraKey } from '@alilc/lowcode-designer';
44

55
const utils = {
66
isNodeSchema,
@@ -9,6 +9,7 @@ const utils = {
99
getNodeSchemaById,
1010
getConvertedExtraKey,
1111
getOriginalExtraKey,
12+
executeTransaction: transactionManager.executeTransaction.bind(transactionManager),
1213
};
1314

1415
export default utils;

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,11 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
349349
* 是否为画布自动渲染
350350
*/
351351
autoRender = true;
352+
353+
/**
354+
* 画布是否自动监听事件来重绘节点
355+
*/
356+
autoRepaintNode = true;
352357
/**
353358
* 加载资源
354359
*/
@@ -491,6 +496,14 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer {
491496
this._appContext = { ...this._appContext };
492497
}
493498

499+
stopAutoRepaintNode() {
500+
this.autoRepaintNode = false;
501+
}
502+
503+
enableAutoRepaintNode() {
504+
this.autoRepaintNode = true;
505+
}
506+
494507
dispose() {
495508
this.disposeFunctions.forEach(fn => fn());
496509
this.documentInstances.forEach(docInst => docInst.dispose());

packages/renderer-core/src/hoc/leaf.tsx

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,23 @@ function initRerenderEvent({
102102
leaf,
103103
dispose: [
104104
leaf?.onPropChange?.(() => {
105+
if (!container.autoRepaintNode) {
106+
return;
107+
}
105108
__debug(`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onPropsChange make rerender`);
106109
container.rerender();
107110
}),
108111
leaf?.onChildrenChange?.(() => {
112+
if (!container.autoRepaintNode) {
113+
return;
114+
}
109115
__debug(`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onChildrenChange make rerender`);
110116
container.rerender();
111117
}) as Function,
112118
leaf?.onVisibleChange?.(() => {
119+
if (!container.autoRepaintNode) {
120+
return;
121+
}
113122
__debug(`${schema.componentName}[${schema.id}] leaf not render in SimulatorRendererView, leaf onVisibleChange make rerender`);
114123
container.rerender();
115124
}),
@@ -213,14 +222,18 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
213222
}
214223

215224
componentDidMount() {
225+
const _leaf = this.leaf;
226+
this.initOnPropsChangeEvent(_leaf);
227+
this.initOnChildrenChangeEvent(_leaf);
228+
this.initOnVisibleChangeEvent(_leaf);
216229
this.recordTime();
217230
}
218231

219-
get defaultState() {
232+
getDefaultState(nextProps: any) {
220233
const {
221234
hidden = false,
222235
condition = true,
223-
} = this.leaf?.export?.(TransformStage.Render) || {};
236+
} = nextProps.__inner__ || this.leaf?.export?.(TransformStage.Render) || {};
224237
return {
225238
nodeChildren: null,
226239
childrenInState: false,
@@ -236,19 +249,15 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
236249
// 监听以下事件,当变化时更新自己
237250
__debug(`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`);
238251
clearRerenderEvent(componentCacheId);
239-
const _leaf = this.leaf;
240-
this.initOnPropsChangeEvent(_leaf);
241-
this.initOnChildrenChangeEvent(_leaf);
242-
this.initOnVisibleChangeEvent(_leaf);
243-
this.curEventLeaf = _leaf;
252+
this.curEventLeaf = this.leaf;
244253

245254
cache.ref.set(componentCacheId, {
246255
makeUnitRender: this.makeUnitRender,
247256
});
248257

249258
let cacheState = cache.state.get(componentCacheId);
250259
if (!cacheState || cacheState.__tag !== props.__tag) {
251-
cacheState = this.defaultState;
260+
cacheState = this.getDefaultState(props);
252261
}
253262

254263
this.state = cacheState;
@@ -279,6 +288,10 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
279288
singleRender?: boolean;
280289
};
281290

291+
get autoRepaintNode() {
292+
return container.autoRepaintNode;
293+
}
294+
282295
judgeMiniUnitRender() {
283296
if (!this.renderUnitInfo) {
284297
this.getRenderUnitInfo();
@@ -380,13 +393,16 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
380393
const {
381394
visible,
382395
...resetState
383-
} = this.defaultState;
396+
} = this.getDefaultState(nextProps);
384397
this.setState(resetState);
385398
}
386399

387400
/** 监听参数变化 */
388401
initOnPropsChangeEvent(leaf = this.leaf): void {
389-
const dispose = leaf?.onPropChange?.(debounce((propChangeInfo: PropChangeOptions) => {
402+
const dispose = leaf?.onPropChange?.((propChangeInfo: PropChangeOptions) => {
403+
if (!this.autoRepaintNode) {
404+
return;
405+
}
390406
const {
391407
key,
392408
newValue = null,
@@ -433,7 +449,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
433449
});
434450

435451
this.judgeMiniUnitRender();
436-
}, 30));
452+
});
437453

438454
dispose && this.disposeFunctions.push(dispose);
439455
}
@@ -443,6 +459,9 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
443459
*/
444460
initOnVisibleChangeEvent(leaf = this.leaf) {
445461
const dispose = leaf?.onVisibleChange?.((flag: boolean) => {
462+
if (!this.autoRepaintNode) {
463+
return;
464+
}
446465
if (this.state.visible === flag) {
447466
return;
448467
}
@@ -463,6 +482,9 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
463482
*/
464483
initOnChildrenChangeEvent(leaf = this.leaf) {
465484
const dispose = leaf?.onChildrenChange?.((param): void => {
485+
if (!this.autoRepaintNode) {
486+
return;
487+
}
466488
const {
467489
type,
468490
node,
@@ -540,6 +562,8 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
540562
ref: forwardedRef,
541563
};
542564

565+
delete compProps.__inner__;
566+
543567
return engine.createElement(Comp, compProps, this.hasChildren ? this.children : null);
544568
}
545569
}

packages/renderer-core/src/renderer/base.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,14 @@ export default function baseRendererFactory(): IBaseRenderComponent {
670670
}
671671
}
672672
}
673-
return renderComp({ ...props, ...otherProps });
673+
return renderComp({
674+
...props,
675+
...otherProps,
676+
__inner__: {
677+
hidden: schema.hidden,
678+
condition,
679+
},
680+
});
674681
} catch (e) {
675682
return engine.createElement(engine.getFaultComponent(), {
676683
error: e,

packages/renderer-core/tests/hoc/leaf.test.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ const baseRenderer: any = {
3535
__container: {
3636
rerender: () => {
3737
rerenderCount = 1 + rerenderCount;
38-
}
38+
},
39+
autoRepaintNode: true,
3940
},
4041
documentId: '01'
4142
},

0 commit comments

Comments
 (0)