UNPKG

fastlion-amis

Version:

一种MIS页面生成工具

132 lines (131 loc) 6.66 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isExpression = exports.FormulaExec = void 0; var tslib_1 = require("tslib"); var amis_formula_1 = require("amis-formula"); var lodash_1 = require("lodash"); var isObject_1 = (0, tslib_1.__importDefault)(require("lodash/isObject")); var grammar_1 = require("./grammar"); var helper_1 = require("./helper"); var tpl_1 = require("./tpl"); var tpl_builtin_1 = require("./tpl-builtin"); /** * formulaExec 运算器:根据当前字符串类型执行对应运算,也可按指定执行模式执行运算 * * 运算模式(execMode)支持以下取值: * 1. tpl: 按模板字符串执行(JavaScript 模板引擎),比如:Hello ${amisUser.email}、<h1>Hello</h1>, <span>${amisUser.email}</span>; * 备注: 在模板中可以自由访问变量,详细请见:https://www.lodashjs.com/docs/lodash.template; * 2. formula: 按新版公式表达式执行,用于执行 ${ xxx } 格式的表达式; * 支持从window、localStorage、sessionStorage获取数据,比如:${num1 + 2}、${ls:env}、${window:document}、${window:document.URL}、${amisUser.email}; * 详细请见:https://aisuda.bce.baidu.com/amis/zh-CN/docs/concepts/data-mapping#namespace * 3. evalFormula: 按新版公式表达式执行,用于执行 ${ xxx } 和 非${ xxx } 格式的表达式(evalMode 为 true,不用 ${} 包裹也可以执行),功能同 formula 运算模式; * 4. js: 按Javascript执行,表达式中可以通过data.xxx来获取指定数据,并且支持简单运算; * 比如:data.num1 + 2、this.num1 + 2、num1 + 2;(备注:三个表达式是等价的,这里的 this 就是 data。) * 5. var: 以此字符串作为key值从当前数据域data中获取数值;性能最高(运行期间不会生成ast和表达式运算); * 6. true 或者 false: 当execMode设置为true时,不用 ${} 包裹也可以执行表达式; * 7. collect: 用于从表达式中获取所有变量; * * 备注1: 用户也可以使用 registerFormulaExec 注册一个自定义运算器; * 备注2: 模板字符串 和 Javascript 模板引擎 不可以交叉使用; * 备注3: amis 现有的 evalFormula 方法,可执行 ${} 格式类表达式,但不支持 filter 过滤器,所以这里用 resolveValueByName 实现; * 备注4: 后续可考虑将 amis现有的运算器都放这里管理,充当统一的运算器入口。 */ // 缓存,用于提升性能 var FORMULA_EVAL_CACHE = {}; /** * 用于存储当前可用运算器,默认支持 tpl、formula、js、var 四种类型运算器 * 备注:在这里统一参数。 */ exports.FormulaExec = { tpl: function (expression, data) { var curData = data || {}; return (0, tpl_1.filter)(expression, curData); }, formula: function (expression, data) { // 邮箱格式直接返回,后续需要在 amis-formula 中处理 if (/^\$\{([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})\}$/.test(expression)) { return expression.substring(2, expression.length - 1); // 剔除前后特殊字符 } var curData = data || {}; var result = undefined; try { // 执行 ${} 格式类表达式,且支持 filter 过滤器。(备注: isPureVariable 可用于判断是否有 过滤器。) result = (0, tpl_builtin_1.resolveVariableAndFilter)(expression, curData, '| raw'); } catch (e) { console.warn('[formula]表达式执行异常,当前表达式: ', expression, ',当前上下文数据: ', data); return expression; } // 备注: 此处不用 result ?? expression 是为了避免 没有对应结果时直接显示 expression: ${xxx} return result; }, evalFormula: function (expression, data) { var curData = data || {}; var result = undefined; try { result = (0, amis_formula_1.evaluate)(expression, curData, { evalMode: true, allowFilter: false }); } catch (e) { console.warn('[evalFormula]表达式执行异常,当前表达式: ', expression, ',当前上下文数据: ', data); return expression; } return result !== null && result !== void 0 ? result : expression; }, js: function (expression, data) { var debug = false; var idx = expression.indexOf('debugger'); if (~idx) { debug = true; expression = expression.replace(/debugger;?/, ''); } var fn; if (expression in FORMULA_EVAL_CACHE) { fn = FORMULA_EVAL_CACHE[expression]; } else { fn = new Function('data', 'utils', "with(data) {" + (debug ? 'debugger;' : '') + "return (" + expression + ");}"); FORMULA_EVAL_CACHE[expression] = fn; } data = data || {}; var curResult = undefined; try { curResult = fn.call(data, data, (0, tpl_builtin_1.getFilters)()); } catch (e) { console.warn('[formula:js]表达式执行异常,当前表达式: ', expression, ',当前上下文数据: ', data); return expression; } return curResult; }, var: function (expression, data) { var curData = data || {}; var result = (0, helper_1.getVariable)(curData, expression); // 不支持过滤器 return result !== null && result !== void 0 ? result : expression; }, collect: function (expression) { var variables = []; if ((0, isObject_1.default)(expression) || (0, lodash_1.isString)(expression)) { // 仅对 Object类型 和 String类型 进行变量提取 variables = (0, grammar_1.collectVariables)(expression); } else { variables = []; } return variables; } }; // 用于判断是否优先使用value。 function isExpression(expression) { if (!expression || !(0, lodash_1.isString)(expression)) { // 非字符串类型,比如:Object、Array类型、boolean、number类型 return false; } // 备注1: "\\${xxx}"不作为表达式,至少含一个${xxx}才算是表达式 // 备注2: safari 不支持 /(?<!\\)(\${).+(\})/.test(expression) return /(^|[^\\])\$\{.+\}/.test(expression); } exports.isExpression = isExpression; //# sourceMappingURL=./utils/formula.js.map