mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-18 21:38:14 +00:00
fix: 修复部分节点无法监听事件问题/修复渲染问题
This commit is contained in:
parent
59af249ac2
commit
4c552124ae
@ -209,6 +209,7 @@ class Renderer extends Component<{
|
||||
onCompGetRef={(schema: any, ref: any) => {
|
||||
documentInstance.mountInstance(schema.id, ref);
|
||||
}}
|
||||
getNode={(id: string) => documentInstance.getNode(id) as any}
|
||||
customCreateElement={(Component: any, props: any, children: any) => {
|
||||
const { __id, ...viewProps } = props;
|
||||
viewProps.componentId = __id;
|
||||
|
||||
@ -4,7 +4,7 @@ import cn from 'classnames';
|
||||
import { Node } from '@ali/lowcode-designer';
|
||||
import LowCodeRenderer from '@ali/lowcode-react-renderer';
|
||||
import { observer } from 'mobx-react';
|
||||
import { getClosestNode } from '@ali/lowcode-utils';
|
||||
import { getClosestNode, isFromVC } from '@ali/lowcode-utils';
|
||||
import { GlobalEvent } from '@ali/lowcode-types';
|
||||
import { SimulatorRendererContainer, DocumentInstance } from './renderer';
|
||||
import { host } from './host';
|
||||
@ -132,6 +132,10 @@ class Renderer extends Component<{
|
||||
startTime: number | null = null;
|
||||
|
||||
componentDidUpdate() {
|
||||
this.recordTime();
|
||||
}
|
||||
|
||||
recordTime() {
|
||||
if (this.startTime) {
|
||||
const time = Date.now() - this.startTime;
|
||||
const nodeCount = host.designer.currentDocument?.getNodeCount?.();
|
||||
@ -144,6 +148,10 @@ class Renderer extends Component<{
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.recordTime();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { documentInstance, rendererContainer: renderer } = this.props;
|
||||
const { container } = documentInstance;
|
||||
@ -166,11 +174,14 @@ class Renderer extends Component<{
|
||||
device={device}
|
||||
suspended={renderer.suspended}
|
||||
self={renderer.scope}
|
||||
getNode={(id: string) => documentInstance.getNode(id) as Node}
|
||||
customCreateElement={(Component: any, props: any, children: any) => {
|
||||
const { __id, ...viewProps } = props;
|
||||
viewProps.componentId = __id;
|
||||
const leaf = documentInstance.getNode(__id) as Node;
|
||||
if (isFromVC(leaf?.componentMeta)) {
|
||||
viewProps._leaf = leaf;
|
||||
}
|
||||
viewProps._componentName = leaf?.componentName;
|
||||
// 如果是容器 && 无children && 高宽为空 增加一个占位容器,方便拖动
|
||||
if (
|
||||
|
||||
@ -4,7 +4,12 @@ import { EngineOptions } from '@ali/lowcode-editor-core';
|
||||
import adapter from '../adapter';
|
||||
import * as types from '../types/index';
|
||||
|
||||
const compDefaultPropertyNames = ['$$typeof', 'render', 'defaultProps'];
|
||||
const compDefaultPropertyNames = [
|
||||
'$$typeof',
|
||||
'render',
|
||||
'defaultProps',
|
||||
'props',
|
||||
];
|
||||
|
||||
export interface IComponentHocInfo {
|
||||
schema: any;
|
||||
@ -31,6 +36,8 @@ interface IProps {
|
||||
componentId?: number;
|
||||
|
||||
children?: Node[];
|
||||
|
||||
__tag?: number;
|
||||
}
|
||||
|
||||
enum RerenderType {
|
||||
@ -55,10 +62,20 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
||||
} = baseRenderer;
|
||||
const engine = baseRenderer.context.engine;
|
||||
const host: BuiltinSimulatorHost = baseRenderer.props.__host;
|
||||
const getNode = baseRenderer.props?.getNode;
|
||||
const container: BuiltinSimulatorHost = baseRenderer.props.__container;
|
||||
const editor = host?.designer?.editor;
|
||||
const { Component } = adapter.getRuntime();
|
||||
|
||||
/** 部分没有渲染的 node 节点进行兜底处理 or 渲染方式没有渲染 LeafWrapper */
|
||||
const leaf = getNode(schema.id);
|
||||
|
||||
const wrapDisposeFunctions: Function[] = [
|
||||
leaf?.onPropsChange?.(() => container.rerender()),
|
||||
leaf?.onChildrenChange?.(() => container.rerender()),
|
||||
leaf?.onVisibleChange?.(() => container.rerender()),
|
||||
];
|
||||
|
||||
class LeafWrapper extends Component {
|
||||
recordInfo: {
|
||||
startTime?: number | null;
|
||||
@ -96,9 +113,11 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
||||
this.initOnPropsChangeEvent();
|
||||
this.initOnChildrenChangeEvent();
|
||||
this.initOnVisibleChangeEvent();
|
||||
wrapDisposeFunctions.forEach(d => d && d());
|
||||
this.state = {
|
||||
nodeChildren: null,
|
||||
childrenInState: false,
|
||||
__tag: props.__tag,
|
||||
};
|
||||
}
|
||||
|
||||
@ -109,8 +128,25 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
||||
this.recordInfo.node = node;
|
||||
}
|
||||
|
||||
get isInWhitelist() {
|
||||
return whitelist.includes(schema.componentName);
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(props: any, state: any) {
|
||||
if (props.__tag === state.__tag) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
nodeChildren: props.children,
|
||||
nodeProps: props.nodeProps,
|
||||
childrenInState: true,
|
||||
__tag: props.__tag,
|
||||
};
|
||||
}
|
||||
|
||||
shouldComponentUpdate() {
|
||||
if (whitelist.includes(schema.componentName)) {
|
||||
if (this.isInWhitelist) {
|
||||
__debug(`${schema.componentName} is in leaf Hoc whitelist`);
|
||||
container.rerender();
|
||||
return false;
|
||||
@ -130,6 +166,7 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
||||
// 如果循坏条件变化,从根节点重新渲染
|
||||
// 目前多层循坏无法判断需要从哪一层开始渲染,故先粗暴解决
|
||||
if (key === '___loop___') {
|
||||
__debug('key is ___loop___, render a page!');
|
||||
container.rerender();
|
||||
return;
|
||||
}
|
||||
@ -218,25 +255,7 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
||||
}
|
||||
|
||||
get leaf(): Node | undefined {
|
||||
return this.props._leaf;
|
||||
}
|
||||
|
||||
get childrenMap(): any {
|
||||
const map = new Map();
|
||||
|
||||
if (!this.hasChildren) {
|
||||
return map;
|
||||
}
|
||||
|
||||
this.children.forEach((d: any) => {
|
||||
if (Array.isArray(d)) {
|
||||
map.set(d[0].props.componentId, d[0]);
|
||||
return;
|
||||
}
|
||||
map.set(d.props.componentId, d);
|
||||
});
|
||||
|
||||
return map;
|
||||
return this.props._leaf || getNode(this.props.componentId);
|
||||
}
|
||||
|
||||
get visible(): boolean {
|
||||
@ -268,6 +287,8 @@ export function leafWrapper(Comp: types.IBaseRenderer, {
|
||||
if (typeof Comp === 'object') {
|
||||
const compExtraPropertyNames = Object.getOwnPropertyNames(Comp).filter(d => !compDefaultPropertyNames.includes(d));
|
||||
|
||||
__debug(`${schema.componentName} extra property names: ${compExtraPropertyNames.join(',')}`);
|
||||
|
||||
compExtraPropertyNames.forEach((d: string) => {
|
||||
(LeafWrapper as any)[d] = Comp[d];
|
||||
});
|
||||
|
||||
@ -342,16 +342,10 @@ export default function baseRenererFactory() {
|
||||
}
|
||||
const _children = this.getSchemaChildren(__schema);
|
||||
let Comp = __components[__schema.componentName];
|
||||
this.componentHoc.forEach((ComponentConstruct: IComponentConstruct) => {
|
||||
Comp = ComponentConstruct(Comp || Div, {
|
||||
schema: __schema,
|
||||
componentInfo: {},
|
||||
baseRenderer: this,
|
||||
});
|
||||
});
|
||||
|
||||
return this.__createVirtualDom(_children, self, ({
|
||||
schema: __schema,
|
||||
Comp,
|
||||
Comp: this.__getHocComp(Comp, __schema),
|
||||
} as IInfo));
|
||||
};
|
||||
|
||||
@ -478,6 +472,9 @@ export default function baseRenererFactory() {
|
||||
if (engine?.props?.designMode) {
|
||||
otherProps.__designMode = engine.props.designMode;
|
||||
}
|
||||
if (this._designModeIsDesign) {
|
||||
otherProps.__tag = Math.random();
|
||||
}
|
||||
const componentInfo: any = {};
|
||||
const props: any = this.__getComponentProps(schema, Comp, {
|
||||
...componentInfo,
|
||||
@ -494,7 +491,6 @@ export default function baseRenererFactory() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 对于可以获取到ref的组件做特殊处理
|
||||
if (!acceptsRef(Comp) && !this.__hoc_components[schema.componentName]) {
|
||||
Comp = compWrapper(Comp);
|
||||
@ -605,8 +601,8 @@ export default function baseRenererFactory() {
|
||||
|
||||
_children.forEach((_child: any) => {
|
||||
const _childVirtualDom = this.__createVirtualDom(
|
||||
isJSExpression(_child) ? parseExpression(_child, self) : _child,
|
||||
self,
|
||||
isJSExpression(_child) ? parseExpression(_child, this.self) : _child,
|
||||
this.self,
|
||||
{
|
||||
schema,
|
||||
Comp,
|
||||
@ -813,7 +809,6 @@ export default function baseRenererFactory() {
|
||||
__renderContextProvider = (customProps?: object, children?: any) => {
|
||||
customProps = customProps || {};
|
||||
children = children || this.__createDom();
|
||||
this.__hoc_components = {};
|
||||
return createElement(AppContext.Provider, {
|
||||
value: {
|
||||
...this.context,
|
||||
@ -828,26 +823,37 @@ export default function baseRenererFactory() {
|
||||
return createElement(AppContext.Consumer, {}, children);
|
||||
};
|
||||
|
||||
__getHocComp(Comp: any, schema: any) {
|
||||
if (!this.__hoc_components[schema.componentName]) {
|
||||
this.componentHoc.forEach((ComponentConstruct: IComponentConstruct) => {
|
||||
Comp = ComponentConstruct(Comp || Div, {
|
||||
schema,
|
||||
componentInfo: {},
|
||||
baseRenderer: this,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
Comp = this.__hoc_components[schema.componentName];
|
||||
this.__hoc_components[schema.componentName] = Comp;
|
||||
}
|
||||
|
||||
return Comp;
|
||||
}
|
||||
|
||||
__renderComp(Comp: any, ctxProps: object) {
|
||||
const { __schema } = this.props;
|
||||
Comp = this.__getHocComp(Comp, __schema);
|
||||
const data = this.__parseProps(__schema?.props, this.self, '', {
|
||||
schema: __schema,
|
||||
Comp,
|
||||
componentInfo: {},
|
||||
});
|
||||
this.__hoc_components = {};
|
||||
const { className } = data;
|
||||
const { engine } = this.context || {};
|
||||
if (!engine) {
|
||||
return null;
|
||||
}
|
||||
this.componentHoc.forEach((ComponentConstruct: IComponentConstruct) => {
|
||||
Comp = ComponentConstruct(Comp || Div, {
|
||||
schema: __schema,
|
||||
componentInfo: {},
|
||||
baseRenderer: this,
|
||||
});
|
||||
});
|
||||
|
||||
const child = engine.createElement(
|
||||
Comp,
|
||||
{
|
||||
|
||||
@ -61,6 +61,14 @@ export function arrShallowEquals(arr1: any[], arr2: any[]): boolean {
|
||||
return arr1.every(item => arr2.includes(item));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前 meta 是否从 vc prototype 转换而来
|
||||
* @param meta
|
||||
*/
|
||||
export function isFromVC(meta: ComponentMeta) {
|
||||
return !!meta?.getMetadata()?.experimental;
|
||||
}
|
||||
|
||||
export function executePendingFn(fn: () => void, timeout: number = 2000) {
|
||||
return setTimeout(fn, timeout);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user