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