我正在制作HTML模板引擎。
程序浏览HTML,找到{{}}的所有实例。然后它遍历我们的countroller中的所有键,并用对控制器的引用替换变量名的实例。
例如,如果我的控制器为{name:"grody"}
且我的HTML为{{name}}
,我的程序将执行以下操作,将其替换为{{ctrl['name']}}
。
然后程序会通过并在所有表达式上使用eval()
来评估它们。
类似于{{name + " joe"}}
- > {{ctrl['name'] + " joe"}}
- > grody joe
我得到的错误是一个ReferenceError,显然发生在函数的eval
内。只有当存在多个变量时才会发生此ReferenceError,并且它会在第一个变量上抛出错误。
例如,如果模板为{{name}} is {{age}} years old}}
,则会在名称上获得ReferenceError。
但是,如果您将名称设为字符串,那么控制器中的"na+me":"grody"
之类的内容将导致ReferenceError:na未定义。
这是代码:
function template(str, ctrl) {
var exp = str.match(/[^{{]+(?=\}})/g).map(function(x) {
return x.replace("}}", "")
})
for (var i = 0; i < exp.length; i++) {
for (var prop in ctrl) {
//console.log("propSearch:", prop.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'))
var evalExp = exp[i].replace(new RegExp(prop.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), "g"), "ctrl['" + prop + "']")
str = str.replace(new RegExp("{{" + exp[i].replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "}}", "g"), eval(evalExp))
//console.log(prop)
//console.log("exp[i]:", exp[i])
//console.log("evalExp:", evalExp)
//console.log("search:", exp[i].replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'))
//console.log("eval:", eval(evalExp))
//console.log("str", str)
evalExp = ""
}
}
return str
}
答案 0 :(得分:1)
我认为你让它变得比它需要的复杂得多。我真的不明白为什么所有这些正则表达式和替换都是必要的。这是一个能够完成您正在寻找的内容的功能:
const mustache = /\{\{(\w+)\}\}/g;
function template(str, ctrl) {
return str.replace(mustache, (match, key) => ctrl[key]);
};
它非常简陋(它只能处理原始字符串键,但不能处理表达式),但您可以处理传递给.replace()
的回调以使其更智能。