Skip to content

Commit c54f369

Browse files
liujupingLeoYuan
authored andcommitted
fix: component cannot be redisplayed by configuration after rendering is closed
1 parent d087092 commit c54f369

File tree

3 files changed

+59
-32
lines changed

3 files changed

+59
-32
lines changed

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

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import { BuiltinSimulatorHost, Node, PropChangeOptions } from '@alilc/lowcode-de
22
import { GlobalEvent, TransformStage, NodeSchema } from '@alilc/lowcode-types';
33
import { isReactComponent, cloneEnumerableProperty } from '@alilc/lowcode-utils';
44
import { EngineOptions } from '@alilc/lowcode-editor-core';
5+
import { debounce } from '../utils/common';
56
import adapter from '../adapter';
67
import * as types from '../types/index';
8+
import { parseData } from '../utils';
79

810
export interface IComponentHocInfo {
911
schema: any;
@@ -23,7 +25,10 @@ export interface IComponentHocState {
2325
childrenInState: boolean;
2426
nodeChildren: any;
2527
nodeCacheProps: any;
28+
/** 控制是否显示隐藏 */
2629
visible: boolean;
30+
/** 控制是否渲染 */
31+
condition: boolean;
2732
nodeProps: any;
2833
}
2934

@@ -58,7 +63,7 @@ enum RerenderType {
5863

5964
// 缓存 Leaf 层组件,防止重新渲染问题
6065
class LeafCache {
61-
constructor(public documentId: string) {
66+
constructor(public documentId: string, public device: string) {
6267
}
6368
/** 组件缓存 */
6469
component = new Map();
@@ -140,6 +145,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
140145
const { engine } = baseRenderer.context;
141146
const host = baseRenderer.props?.__host;
142147
const curDocumentId = baseRenderer.props?.documentId ?? '';
148+
const curDevice = baseRenderer.props?.device ?? '';
143149
const getNode = baseRenderer.props?.getNode;
144150
const container: BuiltinSimulatorHost = baseRenderer.props?.__container;
145151
const setSchemaChangedSymbol = baseRenderer.props?.setSchemaChangedSymbol;
@@ -152,11 +158,11 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
152158

153159
const componentCacheId = schema.id;
154160

155-
if (!cache || (curDocumentId && curDocumentId !== cache.documentId)) {
156-
cache?.event.forEach((event) => {
161+
if (!cache || (curDocumentId && curDocumentId !== cache.documentId) || (curDevice && curDevice !== cache.device)) {
162+
cache?.event.forEach(event => {
157163
event.dispose?.forEach((disposeFn: any) => disposeFn && disposeFn());
158164
});
159-
cache = new LeafCache(curDocumentId);
165+
cache = new LeafCache(curDocumentId, curDevice);
160166
}
161167

162168
if (!isReactComponent(Comp)) {
@@ -231,11 +237,13 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
231237
get defaultState() {
232238
const {
233239
hidden = false,
240+
condition = true,
234241
} = this.leaf?.schema || {};
235242
return {
236243
nodeChildren: null,
237244
childrenInState: false,
238245
visible: !hidden,
246+
condition: parseData(condition, scope),
239247
nodeCacheProps: {},
240248
nodeProps: {},
241249
};
@@ -285,58 +293,64 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
285293
singleRender?: boolean;
286294
};
287295

288-
shouldRenderSingleNode(): boolean {
296+
judgeMiniUnitRender() {
289297
if (!this.renderUnitInfo) {
290298
this.getRenderUnitInfo();
291299
}
292300

293-
const { renderUnitInfo } = this;
301+
const renderUnitInfo = this.renderUnitInfo || {
302+
singleRender: true,
303+
};
294304

295305
if (renderUnitInfo.singleRender) {
296-
return true;
306+
return;
297307
}
298308

299309
const ref = cache.ref.get(renderUnitInfo.minimalUnitId);
300310

301311
if (!ref) {
302312
__debug('Cant find minimalRenderUnit ref! This make rerender!');
303313
container.rerender();
304-
return false;
314+
return;
305315
}
306316
__debug(`${this.leaf?.componentName}(${this.props.componentId}) need render, make its minimalRenderUnit ${renderUnitInfo.minimalUnitName}(${renderUnitInfo.minimalUnitId})`);
307317
ref.makeUnitRender();
308-
309-
return false;
310318
}
311319

312320
getRenderUnitInfo(leaf = this.leaf) {
313-
if (leaf?.isRoot()) {
321+
// leaf 在低代码组件中存在 mock 的情况,退出最小渲染单元判断
322+
if (!leaf || typeof leaf.isRoot !== 'function') {
323+
return;
324+
}
325+
326+
if (leaf.isRoot()) {
314327
this.renderUnitInfo = {
315328
singleRender: true,
316329
...(this.renderUnitInfo || {}),
317330
};
318331
}
319-
if (leaf?.componentMeta.isMinimalRenderUnit) {
332+
if (leaf.componentMeta.isMinimalRenderUnit) {
320333
this.renderUnitInfo = {
321334
minimalUnitId: leaf.id,
322335
minimalUnitName: leaf.componentName,
323336
singleRender: false,
324337
};
325338
}
326-
if (leaf?.hasLoop()) {
339+
if (leaf.hasLoop()) {
327340
// 含有循环配置的元素,父元素是最小渲染单元
328341
this.renderUnitInfo = {
329342
minimalUnitId: leaf?.parent?.id,
330343
minimalUnitName: leaf?.parent?.componentName,
331344
singleRender: false,
332345
};
333346
}
334-
if (leaf?.parent) {
347+
if (leaf.parent) {
335348
this.getRenderUnitInfo(leaf.parent);
336349
}
337350
}
338351

339-
makeUnitRender = () => {
352+
// 最小渲染单元做防抖处理
353+
makeUnitRenderDebounced = debounce(() => {
340354
this.beforeRender(RerenderType.MinimalRenderUnit);
341355
const schema = this.leaf?.export?.(TransformStage.Render);
342356
if (!schema) {
@@ -355,6 +369,10 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
355369

356370
__debug(`${this.leaf?.componentName}(${this.props.componentId}) MinimalRenderUnit Render!`);
357371
this.setState(nextState);
372+
}, 20);
373+
374+
makeUnitRender = () => {
375+
this.makeUnitRenderDebounced();
358376
};
359377

360378
componentWillReceiveProps(nextProps: any) {
@@ -389,6 +407,16 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
389407
} = propChangeInfo;
390408
const node = leaf;
391409

410+
if (key === '___condition___') {
411+
const condition = parseData(newValue, scope);
412+
__debug(`key is ___condition___, change condition value to [${condition}]`);
413+
// 条件表达式改变
414+
this.setState({
415+
condition,
416+
});
417+
return;
418+
}
419+
392420
// 如果循坏条件变化,从根节点重新渲染
393421
// 目前多层循坏无法判断需要从哪一层开始渲染,故先粗暴解决
394422
if (key === '___loop___') {
@@ -398,9 +426,6 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
398426
cache.component.delete(componentCacheId);
399427
return;
400428
}
401-
if (!this.shouldRenderSingleNode()) {
402-
return;
403-
}
404429
this.beforeRender(RerenderType.PropsChanged);
405430
const { state } = this;
406431
const { nodeCacheProps } = state;
@@ -419,6 +444,8 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
419444
nodeProps,
420445
nodeCacheProps,
421446
});
447+
448+
this.judgeMiniUnitRender();
422449
});
423450

424451
dispose && this.disposeFunctions.push(dispose);
@@ -433,15 +460,12 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
433460
return;
434461
}
435462

436-
if (!this.shouldRenderSingleNode()) {
437-
return;
438-
}
439-
440463
__debug(`${leaf?.componentName}[${this.props.componentId}] component trigger onVisibleChange(${flag}) event`);
441464
this.beforeRender(RerenderType.VisibleChanged);
442465
this.setState({
443466
visible: flag,
444467
});
468+
this.judgeMiniUnitRender();
445469
});
446470

447471
dispose && this.disposeFunctions.push(dispose);
@@ -456,26 +480,23 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
456480
type,
457481
node,
458482
} = param || {};
459-
if (!this.shouldRenderSingleNode()) {
460-
return;
461-
}
462483
this.beforeRender(`${RerenderType.ChildChanged}-${type}`, node);
463484
// TODO: 缓存同级其他元素的 children。
464485
// 缓存二级 children Next 查询筛选组件有问题
465486
// 缓存一级 children Next Tab 组件有问题
466-
const nextChild = getChildren(leaf?.export?.(TransformStage.Render) as NodeSchema, scope, Comp); // this.childrenMap
487+
const nextChild = getChildren(leaf?.export?.(TransformStage.Render) as types.ISchema, scope, Comp); // this.childrenMap
467488
__debug(`${schema.componentName}[${this.props.componentId}] component trigger onChildrenChange event`, nextChild);
468489
this.setState({
469490
nodeChildren: nextChild,
470491
childrenInState: true,
471492
});
493+
this.judgeMiniUnitRender();
472494
});
473-
474495
dispose && this.disposeFunctions.push(dispose);
475496
}
476497

477498
componentWillUnmount() {
478-
this.disposeFunctions.forEach((fn) => fn());
499+
this.disposeFunctions.forEach(fn => fn());
479500
}
480501

481502
get hasChildren(): boolean {
@@ -509,7 +530,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, {
509530
}
510531

511532
render() {
512-
if (!this.state.visible) {
533+
if (!this.state.visible || !this.state.condition) {
513534
return null;
514535
}
515536

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,10 @@ export default function baseRendererFactory(): IBaseRenderComponent {
467467
otherProps.__componentName = schema.componentName;
468468
}
469469

470-
if (schema.hidden && (engine?.props?.designMode && engine?.props?.designMode !== 'design')) {
471-
// designMode 为 design 情况下,需要进入 leaf Hoc,进行相关事件注册
470+
// DesignMode 为 design 情况下,需要进入 leaf Hoc,进行相关事件注册
471+
const displayInHook = engine?.props?.designMode === 'design';
472+
473+
if (schema.hidden && !displayInHook) {
472474
return null;
473475
}
474476

@@ -488,7 +490,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
488490
}
489491
}
490492
const condition = schema.condition == null ? true : parseData(schema.condition, scope);
491-
if (!condition) return null;
493+
if (!condition && !displayInHook) return null;
492494

493495
let scopeKey = '';
494496
// 判断组件是否需要生成scope,且只生成一次,挂在this.__compScopes上

packages/renderer-core/src/types/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ export interface IBaseRendererProps {
157157
setSchemaChangedSymbol?: (symbol: boolean) => void;
158158
documentId?: string;
159159
getNode?: any;
160+
/**
161+
* 设备类型,默认值:'default'
162+
*/
163+
device?: 'default' | 'mobile' | string;
160164
}
161165

162166
export interface IInfo {

0 commit comments

Comments
 (0)