我写了这个快速模板功能:
var templatize = function(string) {
return function (string) {
return string.replace(/{{(.*?)}}/g, function(pattern, match) {
value = this[match];
if (value) {
return value;
} else {
return pattern;
}
});
}.call(this, string);
}
这是做什么的:
var foo = "bar", bar = "foo";
templatize("We are {{foo}} and {{bar}}, but not {{crazy}}"); // "We are bar and foo but not {{crazy}}"
除非我有范围问题,否则我对此很满意。当然,可以通过namedscope访问templatize
方法,但是,我的函数无法自动访问当前执行templatize
的上下文。
调用$.proxy(templatize, this)("We are {{foo}} and {{bar}}, but not {{crazy}}")
之类的东西应该有用吗,对吧?
但是我想要实现这一点而不需要调用$ .proxy()(并且最好不使用任何jQuery),以便上下文自动转移到执行者。
我正在努力解决.call()
,.apply()
和其他关闭问题,但我想我在互联网上的某个地方读到这是可能的。感谢
答案 0 :(得分:2)
您可以避免使用jQuery执行此操作:
var templatize = function(string) {
var me = this; // the data source
return string.replace(/{{(.*?)}}/g, function (full, key) {
// "this" refers to the string itself
return me[key] || full;
});
}
如果您想使用jQuery.proxy()
,请换行替换函数:
var templatize = function(string) {
return string.replace(/{{(.*?)}}/g, jQuery.proxy(function (full, key) {
// "this" now refers permanently to the data source
return this[key] || full;
}, this));
}
在这两种情况下,您都可以使用this
将数据源绑定到call
:
templatize.call({ hello: 'Hi!' }, '{{hello}}');
您可以通过编译模板进行优化以便重复使用:
function compile(tpl) {
var i = -1, tmp = [];
tpl = tpl.split(/{{([^{}]+)}}/);
while (++i < tpl.length) {
if (i % 2) tmp.push('this["' + tpl[i] + '"]');
else if (tpl[i]) tmp.push('"' + tpl[i].replace(/"/g, '\\"') + '"');
}
return new Function(
'return [' + tmp.join() + '].join("");'
);
}
用法示例:
var tpl = compile('{{hello}} {{hello}}');
tpl.call({ hello: 'Hi!' }); // "Hi! Hi!"
tpl.call({ hello: 'Yo!' }); // "Yo! Yo!"
关于上面的示例,这是compile
返回的函数:
function () {
return [this["hello"]," ",this["hello"]].join("");
}
请注意,您也可以使用数组:
var tpl = compile('{{1}} {{0}}');
tpl.call(['a', 'b']); // "b a"
答案 1 :(得分:1)
为什么不传递包含视图变量的对象?会更清洁,然后可能在您的视图中显示任何现有变量。
var templatize = function(string, variables) {
return function (string) {
return string.replace(/{{(.*?)}}/g, function(pattern, match) {
value = variables[match];
if (value) {
return value;
} else {
return pattern;
}
});
}.call(this, string);
}