fastlion-amis
Version:
一种MIS页面生成工具
432 lines (431 loc) • 23.6 kB
JavaScript
"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