fastlion-amis
Version:
一种MIS页面生成工具
132 lines (131 loc) • 6.66 kB
JavaScript
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
;