Javascript 动态计算把手模板的值?
有没有一种方法可以在需要时为把手提供一个计算值的函数,而不是在上下文中预先提供所有值 例如,假设我想用示例数据填写任何模板:Javascript 动态计算把手模板的值?,javascript,handlebars.js,Javascript,Handlebars.js,有没有一种方法可以在需要时为把手提供一个计算值的函数,而不是在上下文中预先提供所有值 例如,假设我想用示例数据填写任何模板: var exampleFunction = function (varName) { return "Example " + varName; }; 如果我提前知道Handlebar模板需要什么变量,我可以使用这个函数来组装上下文。然而,我真正想做的是: var template = Handlebars.compile(templateString); var
var exampleFunction = function (varName) {
return "Example " + varName;
};
如果我提前知道Handlebar模板需要什么变量,我可以使用这个函数来组装上下文。然而,我真正想做的是:
var template = Handlebars.compile(templateString);
var html = template.fillFromFunction(exampleFunction);
这可能吗?如果没有,那么还有其他模板引擎支持它吗
附加问题:是否可以使其异步,例如:
var template = Handlebars.compile('{{foo.bar}}');
var dataFunction = function (path, callback) {
setTimeout(function () {
callback("Async " + path);
}, 100);
};
简短版本:
这是一个黑客,但我有一个解决办法
var oldNameLookup = handlebars.JavaScriptCompiler.prototype.nameLookup;
handlebars.JavaScriptCompiler.prototype.nameLookup = function (parent, name) {
return '(typeof ' + parent + ' === "function" ? '
+ parent + '(' + JSON.stringify(name) + ') : '
+ oldNameLookup(parent, name) + ')';
}
用法:
var template = handlebars.compile('{{foo}} {{bar}}');
var dataFunction = function (key) {
return 'data:' + key;
};
console.log(template(dataFunction));
// Outputs: "data:foo data:bar"
var template = handlebars.compile('{{foo}} {{foo.bar}}');
var dataFunction = transformFunc(function (path) {
// path is a JSON Pointer path
return "data:" + path;
});
console.log(template(dataFunction));
// Outputs: "data:/foo data:/foo/bar"
子属性:
要启用子属性(例如,“{{foo.bar}}”
),我们需要一个包装器方法:
function transformFunc(dataFunction) {
return function (key) {
if (typeof key !== 'string') {
return dataFunction('');
}
var pointerKey = '/' + key.replace(/~/g, '~0').replace(/\//g, '~1');
return transformFunc(function (path) {
return dataFunction(pointerKey + path);
});
};
}
用法:
var template = handlebars.compile('{{foo}} {{bar}}');
var dataFunction = function (key) {
return 'data:' + key;
};
console.log(template(dataFunction));
// Outputs: "data:foo data:bar"
var template = handlebars.compile('{{foo}} {{foo.bar}}');
var dataFunction = transformFunc(function (path) {
// path is a JSON Pointer path
return "data:" + path;
});
console.log(template(dataFunction));
// Outputs: "data:/foo data:/foo/bar"
如果需要,我想可以修改.compile()
和.precompile()
,以便在模板化时将transformFunc()
应用于任何传入函数
说明:
黑客包括改变车把的代码生成,但这意味着这是一种OK。我试图找到一种方法来创建子类,但看不到如何获取或使用它
短版本:覆盖。
此方法通常生成JavaScript代码,如depth0.foo
或(depth1&&depth1.bar)
。我们正在对其进行扩展,以便生成的代码首先检查父项
,查看它是否是函数
如果它是一个函数,那么它将以属性名作为参数调用该函数。否则,它将返回与前面相同的值。例如,它将生成如下内容:
(typeof depth0 === "function" ? depth0("foo") : (depth0 && depth0.foo))
对于简单变量(例如just“{{foo}}”
),您现在可以只提供一个函数,并使用变量名调用它
启用子属性
然而,对于嵌套属性(即,“{{foo.bar.baz}}”
),我们实际上需要我们的函数返回另一个函数,该函数可以返回适当的数据,也可以使用另一个属性名调用,具体取决于需要什么
因此:如果我们的转换函数没有给定字符串,那么就假定我们在端点(我们想要的是实际数据,而不是子属性),所以我们只调用它
如果我们的转换函数被赋予一个字符串,那么它被假定为一个键,因此另一个(转换的)函数是return,它调用data函数,并适当地在参数前面加上前缀。我没有额外的分数,因为这不是异步的。我想我会活下去的。