mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-20 07:14:23 +00:00
Merge branch refactor/leafVisible into feat/0.16.14
Title: fix: _leaf 不存在在 props 上时,撤回之后无法修改其属性 Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/6677960
This commit is contained in:
commit
a6d4747e20
@ -185,12 +185,23 @@ class Renderer extends Component<{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
schemaChangedSymbol = false;
|
||||||
|
|
||||||
|
getSchemaChangedSymbol = () => {
|
||||||
|
return this.schemaChangedSymbol;
|
||||||
|
};
|
||||||
|
|
||||||
|
setSchemaChangedSymbol = (symbol: boolean) => {
|
||||||
|
this.schemaChangedSymbol = symbol;
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { documentInstance } = this.props;
|
const { documentInstance } = this.props;
|
||||||
const { container, document } = documentInstance;
|
const { container, document } = documentInstance;
|
||||||
const { designMode, device } = container;
|
const { designMode, device } = container;
|
||||||
const { rendererContainer: renderer } = this.props;
|
const { rendererContainer: renderer } = this.props;
|
||||||
this.startTime = Date.now();
|
this.startTime = Date.now();
|
||||||
|
this.schemaChangedSymbol = false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|||||||
@ -152,12 +152,23 @@ class Renderer extends Component<{
|
|||||||
this.recordTime();
|
this.recordTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
schemaChangedSymbol = false;
|
||||||
|
|
||||||
|
getSchemaChangedSymbol = () => {
|
||||||
|
return this.schemaChangedSymbol;
|
||||||
|
};
|
||||||
|
|
||||||
|
setSchemaChangedSymbol = (symbol: boolean) => {
|
||||||
|
this.schemaChangedSymbol = symbol;
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { documentInstance, rendererContainer: renderer } = this.props;
|
const { documentInstance, rendererContainer: renderer } = this.props;
|
||||||
const { container, document } = documentInstance;
|
const { container, document } = documentInstance;
|
||||||
const { designMode, device, locale } = container;
|
const { designMode, device, locale } = container;
|
||||||
const messages = container.context?.utils?.i18n?.messages || {};
|
const messages = container.context?.utils?.i18n?.messages || {};
|
||||||
this.startTime = Date.now();
|
this.startTime = Date.now();
|
||||||
|
this.schemaChangedSymbol = false;
|
||||||
|
|
||||||
if (!container.autoRender) return null;
|
if (!container.autoRender) return null;
|
||||||
return (
|
return (
|
||||||
@ -175,6 +186,8 @@ class Renderer extends Component<{
|
|||||||
documentId={document.id}
|
documentId={document.id}
|
||||||
suspended={renderer.suspended}
|
suspended={renderer.suspended}
|
||||||
self={renderer.scope}
|
self={renderer.scope}
|
||||||
|
getSchemaChangedSymbol={this.getSchemaChangedSymbol}
|
||||||
|
setSchemaChangedSymbol={this.setSchemaChangedSymbol}
|
||||||
getNode={(id: string) => documentInstance.getNode(id) as Node}
|
getNode={(id: string) => documentInstance.getNode(id) as Node}
|
||||||
rendererName="PageRenderer"
|
rendererName="PageRenderer"
|
||||||
customCreateElement={(Component: any, props: any, children: any) => {
|
customCreateElement={(Component: any, props: any, children: any) => {
|
||||||
|
|||||||
@ -45,32 +45,27 @@ enum RerenderType {
|
|||||||
ChildChanged = 'ChildChanged',
|
ChildChanged = 'ChildChanged',
|
||||||
PropsChanged = 'PropsChanged',
|
PropsChanged = 'PropsChanged',
|
||||||
VisibleChanged = 'VisibleChanged',
|
VisibleChanged = 'VisibleChanged',
|
||||||
LangChanged = 'LangChanged',
|
|
||||||
I18nChanged = 'I18nChanged',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存 Leaf 层组件,防止重新渲染问题
|
// 缓存 Leaf 层组件,防止重新渲染问题
|
||||||
let leafComponentCaches: {
|
class LeafCache {
|
||||||
[componentName: string]: any;
|
constructor(public documentId: string) {
|
||||||
} = {};
|
|
||||||
|
|
||||||
let cacheDocumentId: any;
|
|
||||||
|
|
||||||
function clearCaches(curDocumentId: any, {
|
|
||||||
__debug,
|
|
||||||
}: any) {
|
|
||||||
if (cacheDocumentId === curDocumentId) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
__debug(`DocumentId changed to ${curDocumentId}, clear caches!`);
|
/** 组件缓存 */
|
||||||
cacheDocumentId = curDocumentId;
|
component = new Map();
|
||||||
leafComponentCaches = {};
|
|
||||||
|
/**
|
||||||
|
* 状态缓存,场景:属性变化后,改组件被销毁,state 为空,没有展示修改后的属性
|
||||||
|
*/
|
||||||
|
state = new Map();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订阅事件缓存,导致 rerender 的订阅事件
|
||||||
|
*/
|
||||||
|
event = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存导致 rerender 的订阅事件
|
let cache: LeafCache;
|
||||||
const rerenderEventCache: {
|
|
||||||
[componentId: string]: any;
|
|
||||||
} = {};
|
|
||||||
|
|
||||||
/** 部分没有渲染的 node 节点进行兜底处理 or 渲染方式没有渲染 LeafWrapper */
|
/** 部分没有渲染的 node 节点进行兜底处理 or 渲染方式没有渲染 LeafWrapper */
|
||||||
function initRerenderEvent({
|
function initRerenderEvent({
|
||||||
@ -81,13 +76,13 @@ function initRerenderEvent({
|
|||||||
}: any) {
|
}: any) {
|
||||||
const leaf = getNode?.(schema.id);
|
const leaf = getNode?.(schema.id);
|
||||||
if (!leaf
|
if (!leaf
|
||||||
|| rerenderEventCache[schema.id]?.clear
|
|| cache.event.get(schema.id)?.clear
|
||||||
|| leaf === rerenderEventCache[schema.id]?.leaf
|
|| leaf === cache.event.get(schema.id)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rerenderEventCache[schema.id]?.dispose.forEach((d: any) => d && d());
|
cache.event.get(schema.id)?.dispose.forEach((d: any) => d && d());
|
||||||
rerenderEventCache[schema.id] = {
|
cache.event.set(schema.id, {
|
||||||
clear: false,
|
clear: false,
|
||||||
leaf,
|
leaf,
|
||||||
dispose: [
|
dispose: [
|
||||||
@ -104,21 +99,19 @@ function initRerenderEvent({
|
|||||||
container.rerender();
|
container.rerender();
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 渲染的 node 节点全局注册事件清除 */
|
/** 渲染的 node 节点全局注册事件清除 */
|
||||||
function clearRerenderEvent(id: string): void {
|
function clearRerenderEvent(id: string): void {
|
||||||
if (!rerenderEventCache[id]) {
|
if (cache.event.get(id)?.clear) {
|
||||||
rerenderEventCache[id] = {
|
|
||||||
clear: true,
|
|
||||||
dispose: [],
|
|
||||||
};
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rerenderEventCache[id].dispose.forEach((d: any) => d && d());
|
cache.event.get(id)?.dispose?.forEach((d: any) => d && d());
|
||||||
rerenderEventCache[id].dispose = [];
|
cache.event.set(id, {
|
||||||
rerenderEventCache[id].clear = true;
|
clear: true,
|
||||||
|
dispose: [],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 给每个组件包裹一个 HOC Leaf,支持组件内部属性变化,自响应渲染
|
// 给每个组件包裹一个 HOC Leaf,支持组件内部属性变化,自响应渲染
|
||||||
@ -137,13 +130,12 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
|||||||
const curDocumentId = baseRenderer.props?.documentId;
|
const curDocumentId = baseRenderer.props?.documentId;
|
||||||
const getNode = baseRenderer.props?.getNode;
|
const getNode = baseRenderer.props?.getNode;
|
||||||
const container: BuiltinSimulatorHost = baseRenderer.props.__container;
|
const container: BuiltinSimulatorHost = baseRenderer.props.__container;
|
||||||
|
const setSchemaChangedSymbol = baseRenderer.props?.setSchemaChangedSymbol;
|
||||||
const editor = host?.designer?.editor;
|
const editor = host?.designer?.editor;
|
||||||
const { Component, forwardRef } = adapter.getRuntime();
|
const { Component, forwardRef } = adapter.getRuntime();
|
||||||
|
|
||||||
if (curDocumentId !== cacheDocumentId) {
|
if (!cache || curDocumentId !== cache.documentId) {
|
||||||
clearCaches(curDocumentId, {
|
cache = new LeafCache(curDocumentId);
|
||||||
__debug,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isReactComponent(Comp)) {
|
if (!isReactComponent(Comp)) {
|
||||||
@ -157,8 +149,8 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
|||||||
getNode,
|
getNode,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (leafComponentCaches[schema.componentName]) {
|
if (cache.component.has(schema.componentName)) {
|
||||||
return leafComponentCaches[schema.componentName];
|
return cache.component.get(schema.componentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
class LeafHoc extends Component {
|
class LeafHoc extends Component {
|
||||||
@ -215,18 +207,45 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get defaultState() {
|
||||||
|
const {
|
||||||
|
hidden = false,
|
||||||
|
} = this.leaf?.schema || {};
|
||||||
|
return {
|
||||||
|
nodeChildren: null,
|
||||||
|
childrenInState: false,
|
||||||
|
visible: !hidden,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props: IProps, context: any) {
|
constructor(props: IProps, context: any) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
// 监听以下事件,当变化时更新自己
|
// 监听以下事件,当变化时更新自己
|
||||||
__debug(`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`);
|
__debug(`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`);
|
||||||
clearRerenderEvent(this.props.componentId);
|
clearRerenderEvent(this.props.componentId);
|
||||||
this.initOnPropsChangeEvent();
|
const _leaf = this.leaf;
|
||||||
this.initOnChildrenChangeEvent();
|
this.initOnPropsChangeEvent(_leaf);
|
||||||
this.initOnVisibleChangeEvent();
|
this.initOnChildrenChangeEvent(_leaf);
|
||||||
this.state = {
|
this.initOnVisibleChangeEvent(_leaf);
|
||||||
nodeChildren: null,
|
this.curEventLeaf = _leaf;
|
||||||
childrenInState: false,
|
|
||||||
};
|
let cacheState = cache.state.get(props.componentId);
|
||||||
|
if (!cacheState || cacheState.__tag !== props.__tag) {
|
||||||
|
cacheState = this.defaultState;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state = cacheState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private curEventLeaf;
|
||||||
|
|
||||||
|
setState(state: any) {
|
||||||
|
cache.state.set(this.props.componentId, {
|
||||||
|
...this.state,
|
||||||
|
...state,
|
||||||
|
__tag: this.props.__tag,
|
||||||
|
});
|
||||||
|
super.setState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 由于内部属性变化,在触发渲染前,会执行该函数 */
|
/** 由于内部属性变化,在触发渲染前,会执行该函数 */
|
||||||
@ -234,6 +253,7 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
|||||||
this.recordInfo.startTime = Date.now();
|
this.recordInfo.startTime = Date.now();
|
||||||
this.recordInfo.type = type;
|
this.recordInfo.type = type;
|
||||||
this.recordInfo.node = node;
|
this.recordInfo.node = node;
|
||||||
|
setSchemaChangedSymbol?.(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get isInWhitelist() {
|
// get isInWhitelist() {
|
||||||
@ -241,17 +261,19 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps: any) {
|
componentWillReceiveProps(nextProps: any) {
|
||||||
const { _leaf } = nextProps;
|
let { _leaf, componentId } = nextProps;
|
||||||
if (nextProps.__tag === this.props.__tag) {
|
if (nextProps.__tag === this.props.__tag) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_leaf && this.leaf && _leaf !== this.leaf) {
|
_leaf = _leaf || getNode(componentId);
|
||||||
|
if (_leaf && this.curEventLeaf && _leaf !== this.curEventLeaf) {
|
||||||
this.disposeFunctions.forEach(fn => fn());
|
this.disposeFunctions.forEach(fn => fn());
|
||||||
this.disposeFunctions = [];
|
this.disposeFunctions = [];
|
||||||
this.initOnChildrenChangeEvent(_leaf);
|
this.initOnChildrenChangeEvent(_leaf);
|
||||||
this.initOnPropsChangeEvent(_leaf);
|
this.initOnPropsChangeEvent(_leaf);
|
||||||
this.initOnVisibleChangeEvent(_leaf);
|
this.initOnVisibleChangeEvent(_leaf);
|
||||||
|
this.curEventLeaf = _leaf;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -261,7 +283,6 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 监听参数变化 */
|
/** 监听参数变化 */
|
||||||
initOnPropsChangeEvent(leaf = this.leaf): void {
|
initOnPropsChangeEvent(leaf = this.leaf): void {
|
||||||
const dispose = leaf?.onPropChange?.((propChangeInfo: PropChangeOptions) => {
|
const dispose = leaf?.onPropChange?.((propChangeInfo: PropChangeOptions) => {
|
||||||
@ -383,18 +404,8 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
|||||||
return this.props._leaf || getNode(this.props.componentId);
|
return this.props._leaf || getNode(this.props.componentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
get visible(): boolean {
|
|
||||||
if (typeof this.state.visible === 'boolean') {
|
|
||||||
return this.state.visible;
|
|
||||||
}
|
|
||||||
if (typeof this.leaf?.schema?.hidden === 'boolean') {
|
|
||||||
return !this.leaf?.schema?.hidden;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.visible) {
|
if (!this.state.visible) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +443,7 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
|||||||
|
|
||||||
LeafWrapper.displayName = (Comp as any).displayName;
|
LeafWrapper.displayName = (Comp as any).displayName;
|
||||||
|
|
||||||
leafComponentCaches[schema.componentName] = LeafWrapper;
|
cache.component.set(schema.componentName, LeafWrapper);
|
||||||
|
|
||||||
return LeafWrapper;
|
return LeafWrapper;
|
||||||
}
|
}
|
||||||
@ -148,6 +148,20 @@ export default function baseRenererFactory() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
shouldComponentUpdate() {
|
||||||
|
if (this.props.getSchemaChangedSymbol?.() && this.props.__container?.rerender) {
|
||||||
|
this.props.__container?.rerender();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
forceUpdate() {
|
||||||
|
if (this.shouldComponentUpdate()) {
|
||||||
|
super.forceUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
__setLifeCycleMethods = (method: string, args?: any) => {
|
__setLifeCycleMethods = (method: string, args?: any) => {
|
||||||
const lifeCycleMethods = getValue(this.props.__schema, 'lifeCycles', {});
|
const lifeCycleMethods = getValue(this.props.__schema, 'lifeCycles', {});
|
||||||
let fn = lifeCycleMethods[method];
|
let fn = lifeCycleMethods[method];
|
||||||
|
|||||||
@ -16,6 +16,10 @@ export interface IProps {
|
|||||||
suspended?: boolean;
|
suspended?: boolean;
|
||||||
onCompGetRef?: (schema: ISchema, ref: any) => void;
|
onCompGetRef?: (schema: ISchema, ref: any) => void;
|
||||||
onCompGetCtx?: (schema: ISchema, ref: any) => void;
|
onCompGetCtx?: (schema: ISchema, ref: any) => void;
|
||||||
|
/** 传入的 schema 是否有变更 */
|
||||||
|
getSchemaChangedSymbol: () => boolean;
|
||||||
|
/** 设置 schema 是否有变更 */
|
||||||
|
setSchemaChangedSymbol: (symbol: boolean) => void;
|
||||||
customCreateElement?: (...args: any) => any;
|
customCreateElement?: (...args: any) => any;
|
||||||
rendererName: string;
|
rendererName: string;
|
||||||
notFoundComponent?: any;
|
notFoundComponent?: any;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user