refactor: abstract getSchemaChildren

This commit is contained in:
JackLian 2022-07-15 09:17:22 +08:00 committed by 刘菊萍(絮黎)
parent 706dad4aa5
commit 1fa2694635
3 changed files with 68 additions and 66 deletions

View File

@ -31,7 +31,7 @@ import {
} from '../utils'; } from '../utils';
import { IBaseRendererProps, INodeInfo, IBaseRenderComponent, IBaseRendererContext, IGeneralConstructor, IRendererAppHelper, DataSource } from '../types'; import { IBaseRendererProps, INodeInfo, IBaseRenderComponent, IBaseRendererContext, IGeneralConstructor, IRendererAppHelper, DataSource } from '../types';
import { compWrapper } from '../hoc'; import { compWrapper } from '../hoc';
import { IComponentConstruct, IComponentHoc, leafWrapper } from '../hoc/leaf'; import { IComponentConstruct, leafWrapper } from '../hoc/leaf';
import logger from '../utils/logger'; import logger from '../utils/logger';
import isUseLoop from '../utils/is-use-loop'; import isUseLoop from '../utils/is-use-loop';
@ -67,6 +67,36 @@ export function excuteLifeCycleMethod(context: any, schema: NodeSchema, method:
} }
} }
/**
* get children from a node schema
* @PRIVATE
*/
export function getSchemaChildren(schema: NodeSchema | undefined) {
if (!schema) {
return;
}
if (!schema.props) {
return schema.children;
}
if (!schema.children) {
return schema.props.children;
}
if (!schema.props.children) {
return schema.children;
}
let result = ([] as NodeData[]).concat(schema.children);
if (Array.isArray(schema.props.children)) {
result = result.concat(schema.props.children);
} else {
result.push(schema.props.children);
}
return result;
}
export default function baseRendererFactory(): IBaseRenderComponent { export default function baseRendererFactory(): IBaseRenderComponent {
const { BaseRenderer: customBaseRenderer } = adapter.getRenderers(); const { BaseRenderer: customBaseRenderer } = adapter.getRenderers();
@ -114,6 +144,11 @@ export default function baseRendererFactory(): IBaseRenderComponent {
__compScopes: Record<string, any> = {}; __compScopes: Record<string, any> = {};
__instanceMap: Record<string, any> = {}; __instanceMap: Record<string, any> = {};
__dataHelper: any; __dataHelper: any;
/**
* keep track of customMethods added to this context
*
* @type {any}
*/
__customMethodsList: any[] = []; __customMethodsList: any[] = [];
__parseExpression: any; __parseExpression: any;
__ref: any; __ref: any;
@ -235,12 +270,11 @@ export default function baseRendererFactory(): IBaseRenderComponent {
__bindCustomMethods = (props: IBaseRendererProps) => { __bindCustomMethods = (props: IBaseRendererProps) => {
const { __schema } = props; const { __schema } = props;
const customMethodsList = Object.keys(__schema.methods || {}) || []; const customMethodsList = Object.keys(__schema.methods || {}) || [];
this.__customMethodsList (this.__customMethodsList || []).forEach((item: any) => {
&& this.__customMethodsList.forEach((item: any) => { if (!customMethodsList.includes(item)) {
if (!customMethodsList.includes(item)) { delete this[item];
delete this[item]; }
} });
});
this.__customMethodsList = customMethodsList; this.__customMethodsList = customMethodsList;
forEach(__schema.methods, (val: any, key: string) => { forEach(__schema.methods, (val: any, key: string) => {
let value = val; let value = val;
@ -248,7 +282,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
value = this.__parseExpression(value, this); value = this.__parseExpression(value, this);
} }
if (typeof value !== 'function') { if (typeof value !== 'function') {
console.error(`自定义函数${key}类型不符`, value); console.error(`custom method ${key} can not be parsed to a valid function`, value);
return; return;
} }
this[key] = value.bind(this); this[key] = value.bind(this);
@ -282,6 +316,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
}; };
const dataSource = schema.dataSource || defaultDataSource; const dataSource = schema.dataSource || defaultDataSource;
// requestHandlersMap 存在才走数据源引擎方案 // requestHandlersMap 存在才走数据源引擎方案
// TODO: 下面if else 抽成独立函数
const useDataSourceEngine = !!(props.__appHelper?.requestHandlersMap); const useDataSourceEngine = !!(props.__appHelper?.requestHandlersMap);
if (useDataSourceEngine) { if (useDataSourceEngine) {
this.__dataHelper = { this.__dataHelper = {
@ -396,48 +431,22 @@ export default function baseRendererFactory(): IBaseRenderComponent {
this.__ref = ref; this.__ref = ref;
}; };
__getSchemaChildren = (schema: NodeSchema | undefined) => {
if (!schema) {
return;
}
if (!schema.props) {
return schema.children;
}
if (!schema.children) {
return schema.props.children;
}
if (!schema.props.children) {
return schema.children;
}
let _children = ([] as NodeData[]).concat(schema.children);
if (Array.isArray(schema.props.children)) {
_children = _children.concat(schema.props.children);
} else {
_children.push(schema.props.children);
}
return _children;
};
__createDom = () => { __createDom = () => {
const { __schema, __ctx, __components = {} } = this.props; const { __schema, __ctx, __components = {} } = this.props;
const scope: any = {}; const scope: any = {};
scope.__proto__ = __ctx || this; scope.__proto__ = __ctx || this;
const _children = this.__getSchemaChildren(__schema); const _children = getSchemaChildren(__schema);
let Comp = __components[__schema.componentName]; let Comp = __components[__schema.componentName];
if (!Comp) { if (!Comp) {
this.__debug(`${__schema.componentName} is invalid!`); this.__debug(`${__schema.componentName} is invalid!`);
} }
const parentNodeInfo = ({
return this.__createVirtualDom(_children, scope, ({
schema: __schema, schema: __schema,
Comp: this.__getHocComp(Comp, __schema, scope), Comp: this.__getHOCWrappedComponent(Comp, __schema, scope),
} as INodeInfo)); } as INodeInfo);
return this.__createVirtualDom(_children, scope, parentNodeInfo);
}; };
/** /**
@ -486,7 +495,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
return schema.map((item, idy) => this.__createVirtualDom(item, scope, parentInfo, (item as NodeSchema)?.__ctx?.lceKey ? '' : String(idy))); return schema.map((item, idy) => this.__createVirtualDom(item, scope, parentInfo, (item as NodeSchema)?.__ctx?.lceKey ? '' : String(idy)));
} }
const _children = this.__getSchemaChildren(schema); const _children = getSchemaChildren(schema);
// 解析占位组件 // 解析占位组件
if (schema.componentName === 'Fragment' && _children) { if (schema.componentName === 'Fragment' && _children) {
const tarChildren = isJSExpression(_children) ? this.__parseExpression(_children, scope) : _children; const tarChildren = isJSExpression(_children) ? this.__parseExpression(_children, scope) : _children;
@ -593,7 +602,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
props: transformArrayToMap(componentInfo.props, 'name'), props: transformArrayToMap(componentInfo.props, 'name'),
}) || {}; }) || {};
this.__componentHoc.forEach((ComponentConstruct: IComponentConstruct) => { this.__componentHOCs.forEach((ComponentConstruct: IComponentConstruct) => {
Comp = ComponentConstruct(Comp, { Comp = ComponentConstruct(Comp, {
schema, schema,
componentInfo, componentInfo,
@ -676,27 +685,21 @@ export default function baseRendererFactory(): IBaseRenderComponent {
} }
}; };
get __componentHoc(): IComponentConstruct[] { /**
const componentHoc: IComponentHoc[] = [ * get Component HOCs
{ *
designMode: 'design', * @readonly
hoc: leafWrapper, * @type {IComponentConstruct[]}
}, */
]; get __componentHOCs(): IComponentConstruct[] {
if (this.__designModeIsDesign) {
return componentHoc return [leafWrapper];
.filter((d: IComponentHoc) => { }
if (Array.isArray(d.designMode)) { return [];
return d.designMode.includes(this.props.designMode);
}
return d.designMode === this.props.designMode;
})
.map((d: IComponentHoc) => d.hoc);
} }
__getSchemaChildrenVirtualDom = (schema: NodeSchema | undefined, scope: any, Comp: any) => { __getSchemaChildrenVirtualDom = (schema: NodeSchema | undefined, scope: any, Comp: any) => {
let children = this.__getSchemaChildren(schema); let children = getSchemaChildren(schema);
// @todo 补完这里的 Element 定义 @承虎 // @todo 补完这里的 Element 定义 @承虎
let result: any = []; let result: any = [];
@ -922,9 +925,9 @@ export default function baseRendererFactory(): IBaseRenderComponent {
return createElement(AppContext.Consumer, {}, children); return createElement(AppContext.Consumer, {}, children);
}; };
__getHocComp(OriginalComp: any, schema: any, scope: any) { __getHOCWrappedComponent(OriginalComp: any, schema: any, scope: any) {
let Comp = OriginalComp; let Comp = OriginalComp;
this.__componentHoc.forEach((ComponentConstruct: IComponentConstruct) => { this.__componentHOCs.forEach((ComponentConstruct: IComponentConstruct) => {
Comp = ComponentConstruct(Comp || Div, { Comp = ComponentConstruct(Comp || Div, {
schema, schema,
componentInfo: {}, componentInfo: {},
@ -941,7 +944,7 @@ export default function baseRendererFactory(): IBaseRenderComponent {
const { __schema, __ctx } = this.props; const { __schema, __ctx } = this.props;
const scope: any = {}; const scope: any = {};
scope.__proto__ = __ctx || this; scope.__proto__ = __ctx || this;
Comp = this.__getHocComp(Comp, __schema, scope); Comp = this.__getHOCWrappedComponent(Comp, __schema, scope);
const data = this.__parseProps(__schema?.props, scope, '', { const data = this.__parseProps(__schema?.props, scope, '', {
schema: __schema, schema: __schema,
Comp, Comp,

View File

@ -236,7 +236,6 @@ export type IBaseRendererInstance = IGeneralComponent<
> >
& { & {
reloadDataSource(): Promise<any>; reloadDataSource(): Promise<any>;
__getSchemaChildren(schema: NodeSchema | undefined): NodeData | NodeData[] | undefined;
__beforeInit(props: IBaseRendererProps): void; __beforeInit(props: IBaseRendererProps): void;
__init(props: IBaseRendererProps): void; __init(props: IBaseRendererProps): void;
__afterInit(props: IBaseRendererProps): void; __afterInit(props: IBaseRendererProps): void;

View File

@ -154,7 +154,7 @@ describe('Base Render methods', () => {
// it('__render should work', () => { // it('__render should work', () => {
// }); // });
// it('__getSchemaChildren should work', () => { // it('getSchemaChildren should work', () => {
// }); // });
// it('__createDom should work', () => { // it('__createDom should work', () => {
@ -163,7 +163,7 @@ describe('Base Render methods', () => {
// it('__createVirtualDom should work', () => { // it('__createVirtualDom should work', () => {
// }); // });
// it('__componentHoc should work', () => { // it('__componentHOCs should work', () => {
// }); // });
// it('__getSchemaChildrenVirtualDom should work', () => { // it('__getSchemaChildrenVirtualDom should work', () => {
@ -190,7 +190,7 @@ describe('Base Render methods', () => {
// it('__renderContextConsumer should work', () => { // it('__renderContextConsumer should work', () => {
// }); // });
// it('__getHocComp should work', () => { // it('__getHOCWrappedComponent should work', () => {
// }); // });
// it('__renderComp should work', () => { // it('__renderComp should work', () => {