UNPKG

fastlion-amis

Version:

一种MIS页面生成工具

432 lines (431 loc) 23.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SchemaRenderer = void 0; var tslib_1 = require("tslib"); var difference_1 = (0, tslib_1.__importDefault)(require("lodash/difference")); var omit_1 = (0, tslib_1.__importDefault)(require("lodash/omit")); var react_1 = (0, tslib_1.__importDefault)(require("react")); var LazyComponent_1 = (0, tslib_1.__importDefault)(require("./components/LazyComponent")); var factory_1 = require("./factory"); var Item_1 = require("./renderers/Form/Item"); var Root_1 = require("./Root"); var Scoped_1 = require("./Scoped"); var filter_schema_1 = (0, tslib_1.__importDefault)(require("./utils/filter-schema")); var helper_1 = require("./utils/helper"); var SimpleMap_1 = require("./utils/SimpleMap"); var lodash_1 = require("lodash"); var defaultOmitList = [ 'type', 'name', '$ref', 'className', 'data', 'children', 'ref', 'visible', 'visibleOn', 'hidden', 'hiddenOn', 'disabled', 'disabledOn', 'component', 'detectField', 'defaultValue', 'defaultData', 'required', 'requiredOn', 'syncSuperStore', 'mode', 'body' ]; var componentCache = new SimpleMap_1.SimpleMap(); var BroadcastCmpt = /** @class */ (function (_super) { (0, tslib_1.__extends)(BroadcastCmpt, _super); function BroadcastCmpt(props, context) { var _this = _super.call(this, props) || this; _this.unbindEvent = undefined; _this.triggerEvent = _this.triggerEvent.bind(_this); return _this; } BroadcastCmpt.prototype.componentDidMount = function () { var env = this.props.env; this.unbindEvent = env.bindEvent(this.ref); }; BroadcastCmpt.prototype.componentWillUnmount = function () { var _a; (_a = this.unbindEvent) === null || _a === void 0 ? void 0 : _a.call(this); this.ref = null; // 解绑定 }; BroadcastCmpt.prototype.getWrappedInstance = function () { return this.ref; }; BroadcastCmpt.prototype.triggerEvent = function (e, data) { return (0, tslib_1.__awaiter)(this, void 0, Promise, function () { return (0, tslib_1.__generator)(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.props.env.dispatchEvent(e, this.ref, this.context, data)]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; BroadcastCmpt.prototype.childRef = function (ref) { while (ref && ref.getWrappedInstance) { ref = ref.getWrappedInstance(); } this.ref = ref; }; BroadcastCmpt.prototype.render = function () { var _a; var _b = this.props, Component = _b.component, rest = (0, tslib_1.__rest)(_b, ["component"]); var isClassComponent = (_a = Component.prototype) === null || _a === void 0 ? void 0 : _a.isReactComponent; // 函数组件不支持 ref https://reactjs.org/docs/refs-and-the-dom.html#refs-and-function-components return isClassComponent ? (react_1.default.createElement(Component, (0, tslib_1.__assign)({ ref: this.childRef }, rest, { dispatchEvent: this.triggerEvent }))) : (react_1.default.createElement(Component, (0, tslib_1.__assign)({}, rest, { dispatchEvent: this.triggerEvent }))); }; BroadcastCmpt.contextType = Scoped_1.ScopedContext; (0, tslib_1.__decorate)([ helper_1.autobind, (0, tslib_1.__metadata)("design:type", Function), (0, tslib_1.__metadata)("design:paramtypes", [Object]), (0, tslib_1.__metadata)("design:returntype", void 0) ], BroadcastCmpt.prototype, "childRef", null); return BroadcastCmpt; }(react_1.default.Component)); var renderCount = 0; var renderCountTimer; var SchemaRenderer = /** @class */ (function (_super) { (0, tslib_1.__extends)(SchemaRenderer, _super); function SchemaRenderer(props) { var _this = _super.call(this, props) || this; _this.rendererKey = ''; _this.refFn = _this.refFn.bind(_this); _this.renderChild = _this.renderChild.bind(_this); _this.reRender = _this.reRender.bind(_this); _this.resolveRenderer(_this.props); return _this; } SchemaRenderer.prototype.componentWillUnmount = function () { this.ref = null; }; // 限制:只有 schema 除外的 props 变化,或者 schema 里面的某个成员值发生变化才更新。 SchemaRenderer.prototype.shouldComponentUpdate = function (nextProps) { // if (!renderCountTimer) clearTimeout(renderCountTimer) // renderCountTimer = setTimeout(() => { // renderCount = 0 // clearTimeout(renderCountTimer) // renderCountTimer = null // }, 1000) var _a, _b, _c, _d, _e, _f, _g; var schemaType = this.props.schema.type; if (nextProps.schema.type !== schemaType) { return true; } // 判断一下,若是表格或者单元格,则数据没变化,则不更新 if (schemaType === 'cell') { var cellOriStype = this.props.style; var cellNextStype = nextProps.style; // 一键列宽功能 if (this.props.autoWidth !== nextProps.autoWidth) { return true; } if (this.props.tableRotate !== nextProps.tableRotate) return true; if ((0, helper_1.anyChanged)(['left', 'position', 'right', 'zIndex', 'top'], cellOriStype, cellNextStype)) { return true; } if (this.props.className != nextProps.className) { return true; } var originColWidth = this.props.schema.column.width; var nextColWidth = nextProps.schema.column.width; if (originColWidth != nextColWidth) { return true; } // 超级表头删除头部时会数据错乱,就更新有超级表头的 var groupDisabled = this.props.schema.groupName ? true : false; if (groupDisabled) { return true; } var cellOriType = this.props.schema.column.type; if (cellOriType === 'operation') { var operationCol = this.props.fold !== nextProps.fold; if (operationCol) { return true; } return !(0, lodash_1.isEqual)(this.props.data, nextProps.data); } else { var isNoDiff = (this.props.value === nextProps.value) || (this.props.value == nextProps.value); if (this.props.schema.name !== nextProps.schema.name) { return true; } if ((_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.schema) === null || _b === void 0 ? void 0 : _b.linkId) { if ((0, helper_1.anyChanged)(['data'], this.props, nextProps)) { return true; } } if (isNoDiff) { var quickexist = this.props.schema.quickEdit; if (quickexist) { return !(0, lodash_1.isEqual)(this.props.data, nextProps.data); } return false; } else { return true; } } } if (schemaType === 'table') { if (this.props.autoWidth !== nextProps.autoWidth) { return true; } var schemaOriType = (_c = this.props.schema.$schema) === null || _c === void 0 ? void 0 : _c.type; //解决tabs一次性加载时,后面的table高度计算时获取不到在dom中的定位导致高度计算错误 if (this.props.tabsdefer !== nextProps.tabsdefer) { return true; } if (this.props.showColumnsFilter !== nextProps.showColumnsFilter) { return true; } if (schemaOriType === 'crud') { var operationCol = this.props.foldColumns !== nextProps.foldColumns; if (operationCol) { return true; } if (this.props.tableRotate != nextProps.tableRotate) { return true; } if (this.props.loadmoreLoading != nextProps.loadmoreLoading) { return true; } var propsItems = (_d = this.props.data) === null || _d === void 0 ? void 0 : _d.items; var nextPropsItems = (_e = nextProps.data) === null || _e === void 0 ? void 0 : _e.items; var isNoDiff = (propsItems === nextPropsItems) || (propsItems == nextPropsItems); if (isNoDiff && ((_g = (_f = this.props.data) === null || _f === void 0 ? void 0 : _f.items) === null || _g === void 0 ? void 0 : _g.length) !== 0) { return false; } else { return true; } } } var props = this.props; var propsDiff = (0, difference_1.default)(Object.keys(props), ['schema', 'scope']); var nextPropsDiff = (0, difference_1.default)(Object.keys(nextProps), ['schema', 'scope']); var changeProps = (0, helper_1.getChangedProp)(nextPropsDiff, props, nextProps); if (propsDiff.length !== nextPropsDiff.length || changeProps.length) { // // 文本类型不影响渲染的属性-根据对应的组件得出 // const notChangeContainerType = ["formPristine", "userChange"] // // 外部容器类型的组件,仅有data变化 不重新渲染 或者style没有具体变化 // if (!changeProps.some(_ => !([...notChangeContainerType, "data"].includes(_.key) || (_.key === 'style' && JSON.stringify(_.fromValue) === JSON.stringify(_.toValue)))) && ['drawer', 'dialog'].includes(schemaType)) { // return false // } // // 外部容器类型的组件,仅有data变化 不重新渲染 或者style没有具体变化 // if (!changeProps.some(_ => !(notChangeContainerType.includes(_.key) || (_.key === 'style' && JSON.stringify(_.fromValue) === JSON.stringify(_.toValue)))) && ['crud', 'form'].includes(schemaType)) { // return false // } // // 文本类型不影响渲染的属性-根据对应的组件得出 // const notChangeType = ['itemsRaw', 'loadHasMore', 'query', 'orders', 'onAction', 'userChange'] // // 文本类型 'itemsRaw', 'loadHasMore', 'query', 'orders', 'onAction', "$schema" 完全不影响业务 跳过渲染 // if (!changeProps.some(_ => !([...notChangeType, 'data'].includes(_.key) || (_.key === 'style' && JSON.stringify(_.fromValue) === JSON.stringify(_.toValue)))) && ['button', 'pagination', 'date', 'input-text', 'input-number', 'theme'].includes(schemaType)) // return false // // 文本类型 ' // if (!changeProps.some(_ => !(notChangeType.includes(_.key) || (_.key === 'style' && JSON.stringify(_.fromValue) === JSON.stringify(_.toValue)))) && ['action', 'service', 'tpl', 'lion-tpl'].includes(schemaType)) // return false // if (changeProps.length) { // console.log('属性变化触发渲染', schemaType, '变化属性', changeProps, '组件实例', this) // } return true; } else { var nextPropsSchemaList = Object.keys(nextProps.schema); var propsSchemaList = Object.keys(props.schema); if (propsSchemaList.length !== nextPropsSchemaList.length || (0, helper_1.anyChanged)(nextPropsSchemaList, props.schema, nextProps.schema)) { return true; } } return false; }; // Jay // 设置初始时 hidden 或 hiddenOn 就为 true 的input-table对应在数据域里的数据为{}, // 因为初始时 hidden 或 hiddenOn 就为 true的组件不会渲染,所以数据不会经过input-table处理 // 因此在这里处理下初始时隐藏的input-table SchemaRenderer.prototype.componentDidUpdate = function () { var _a; var _b, _c, _d; var _e = this.props, schema = _e.schema, rest = (0, tslib_1.__rest)(_e, ["schema"]); if ((schema.type === 'input-table' || schema.type === 'input-table-field') && !((_b = rest.store) === null || _b === void 0 ? void 0 : _b.hiddenIputTable[schema.name]) && ((_c = rest.store) === null || _c === void 0 ? void 0 : _c.data[schema.name])) { var detectData = rest.data; var exprProps = detectData ? (0, filter_schema_1.default)(schema, detectData, undefined, rest) : {}; if ((exprProps === null || exprProps === void 0 ? void 0 : exprProps.hidden) || (exprProps === null || exprProps === void 0 ? void 0 : exprProps.visible) === false) { (_d = rest.store) === null || _d === void 0 ? void 0 : _d.updateHiddenInputTable((_a = {}, _a[schema.name] = {}, _a)); } } }; SchemaRenderer.prototype.resolveRenderer = function (props, force) { if (force === void 0) { force = false; } var schema = props.schema; var path = props.$path; if (schema && schema.$ref) { schema = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, props.resolveDefinitions(schema.$ref)), schema); path = path.replace(/(?!.*\/).*/, schema.type); } if ((schema === null || schema === void 0 ? void 0 : schema.type) && (force || !this.renderer || this.rendererKey !== schema.type + "-" + schema.$$id)) { var rendererResolver = props.env.rendererResolver || factory_1.resolveRenderer; this.renderer = rendererResolver(path, schema, props); this.rendererKey = schema.type + "-" + schema.$$id; } else { // 自定义组件如果在节点设置了 label name 什么的,就用 formItem 包一层 // 至少自动支持了 valdiations, label, description 等逻辑。 if (schema.children && !schema.component && schema.asFormItem) { schema.component = PlaceholderComponent; schema.renderChildren = schema.children; delete schema.children; } if (schema.component && !schema.component.wrapedAsFormItem && schema.asFormItem) { var cache = componentCache.get(schema.component); if (cache) { schema.component = cache; } else { var cache_1 = (0, Item_1.asFormItem)((0, tslib_1.__assign)({ strictMode: false }, schema.asFormItem))(schema.component); componentCache.set(schema.component, cache_1); cache_1.wrapedAsFormItem = true; schema.component = cache_1; } } } return { path: path, schema: schema }; }; SchemaRenderer.prototype.getWrappedInstance = function () { return this.ref; }; SchemaRenderer.prototype.refFn = function (ref) { this.ref = ref; }; SchemaRenderer.prototype.renderChild = function (region, node, subProps) { if (subProps === void 0) { subProps = {}; } var _a = this.props, _ = _a.schema, __ = _a.$path, env = _a.env, rest = (0, tslib_1.__rest)(_a, ["schema", "$path", "env"]); var $path = this.resolveRenderer(this.props).path; var omitList = defaultOmitList.concat(); // 手动调用检测 如果不通过也不用走下面了 if (this.renderer) { var Component = this.renderer.component; Component.propsList && omitList.push.apply(omitList, Component.propsList); } return (0, Root_1.renderChild)("" + $path + (region ? "/" + region : ''), node || '', (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, (0, omit_1.default)(rest, omitList)), subProps), { data: subProps.data || rest.data, env: env })); }; SchemaRenderer.prototype.reRender = function () { this.resolveRenderer(this.props, true); this.forceUpdate(); }; SchemaRenderer.prototype.render = function () { var _this = this; var _a, _b; var _c = this.props, _ = _c.$path, __ = _c.schema, rest = (0, tslib_1.__rest)(_c, ["$path", "schema"]); if (__ == null) { return null; } var _d = this.resolveRenderer(this.props), $path = _d.path, schema = _d.schema; var theme = this.props.env.theme; if (Array.isArray(schema)) { return (0, Root_1.renderChildren)($path, schema, rest); } var detectData = schema && (schema.detectField === '&' ? rest : rest[schema.detectField || 'data']); var exprProps = detectData ? (0, filter_schema_1.default)(schema, detectData, undefined, rest) : {}; if (exprProps && ((exprProps === null || exprProps === void 0 ? void 0 : exprProps.hidden) || (exprProps === null || exprProps === void 0 ? void 0 : exprProps.visible) === false || (schema === null || schema === void 0 ? void 0 : schema.hidden) || (schema === null || schema === void 0 ? void 0 : schema.visible) === false || (rest === null || rest === void 0 ? void 0 : rest.hidden) || (rest === null || rest === void 0 ? void 0 : rest.visible) === false)) { rest.invisible = true; } if (schema.children) { return rest.invisible ? null : react_1.default.isValidElement(schema.children) ? schema.children : schema.children((0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, rest), exprProps), { $path: $path, $schema: schema, render: this.renderChild, forwardedRef: this.refFn })); } else if (typeof schema.component === 'function') { var isSFC = !(schema.component.prototype instanceof react_1.default.Component); var defaultData_1 = schema.data, defaultValue_1 = schema.value, defaultActiveKey_1 = schema.activeKey, propKey_1 = schema.key, restSchema_1 = (0, tslib_1.__rest)(schema, ["data", "value", "activeKey", "key"]); return rest.invisible ? null : react_1.default.createElement(schema.component, (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, rest), restSchema_1), exprProps), { defaultData: defaultData_1, defaultValue: defaultValue_1, defaultActiveKey: defaultActiveKey_1, propKey: propKey_1, $path: $path, $schema: schema, ref: isSFC ? undefined : this.refFn, forwardedRef: isSFC ? this.refFn : undefined, render: this.renderChild })); } else if (Object.keys(schema).length === 0) { return null; } else if (!this.renderer) { return rest.invisible ? null : (react_1.default.createElement(LazyComponent_1.default, (0, tslib_1.__assign)({}, rest, exprProps, { getComponent: function () { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () { var result; return (0, tslib_1.__generator)(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, rest.env.loadRenderer(schema, $path, this.reRender)]; case 1: result = _a.sent(); if (result && typeof result === 'function') { return [2 /*return*/, result]; } else if (result && react_1.default.isValidElement(result)) { return [2 /*return*/, function () { return result; }]; } this.reRender(); return [2 /*return*/, function () { return (0, factory_1.loadRenderer)(schema, $path); }]; } }); }); }, "$path": $path, "$schema": schema, retry: this.reRender }))); } var renderer = this.renderer; schema = (0, factory_1.filterSchema)(schema, renderer, rest); var defaultData = schema.data, defaultValue = schema.value, propKey = schema.key, defaultActiveKey = schema.activeKey, restSchema = (0, tslib_1.__rest)(schema, ["data", "value", "key", "activeKey"]); var Component = renderer.component; // 原来表单项的 visible: false 和 hidden: true 表单项的值和验证是有效的 // 而 visibleOn 和 hiddenOn 是无效的, // 这个本来就是个bug,但是已经被广泛使用了 // 我只能继续实现这个bug了 if (rest.invisible && ((exprProps === null || exprProps === void 0 ? void 0 : exprProps.hidden) || (exprProps === null || exprProps === void 0 ? void 0 : exprProps.visible) === false || !renderer.isFormItem || ((schema === null || schema === void 0 ? void 0 : schema.visible) !== false && !(schema === null || schema === void 0 ? void 0 : schema.hidden)))) { return null; } var component = (react_1.default.createElement(BroadcastCmpt, (0, tslib_1.__assign)({}, theme.getRendererConfig(renderer.name), restSchema, (0, helper_1.chainEvents)(rest, restSchema), exprProps, { defaultData: (_a = restSchema.defaultData) !== null && _a !== void 0 ? _a : defaultData, defaultValue: (_b = restSchema.defaultValue) !== null && _b !== void 0 ? _b : defaultValue, defaultActiveKey: defaultActiveKey, propKey: propKey, "$path": $path, "$schema": (0, tslib_1.__assign)((0, tslib_1.__assign)({}, schema), exprProps), ref: this.refFn, render: this.renderChild, component: Component }))); return component; }; SchemaRenderer.displayName = 'Renderer'; return SchemaRenderer; }(react_1.default.Component)); exports.SchemaRenderer = SchemaRenderer; var PlaceholderComponent = /** @class */ (function (_super) { (0, tslib_1.__extends)(PlaceholderComponent, _super); function PlaceholderComponent() { return _super !== null && _super.apply(this, arguments) || this; } PlaceholderComponent.prototype.render = function () { var _a = this.props, renderChildren = _a.renderChildren, rest = (0, tslib_1.__rest)(_a, ["renderChildren"]); if (typeof renderChildren === 'function') { return renderChildren(rest); } return null; }; return PlaceholderComponent; }(react_1.default.Component)); //# sourceMappingURL=./SchemaRenderer.js.map