Fer*_*gal 6 javascript templates dot.js
假设我有这样的数据结构:
{ list: [ {
name: "1",
children: [{
name: "1.1",
children: []
},
{
name: "1.2",
children: [{
name: "1.2.1",
children: []
}
]
}
]
},
{
name: "2",
children: [{
name: "2.1",
children: [{
name: "2.1.1",
children: []
},
{
name: "2.1.2",
children: []
},
{
name: "2.1.3",
children: []
}
]
},
{
name: "2.2",
children: []
},
{
name: "2.3",
children: []
}
]
},
{
name: "3",
children: [{
name: "3.1",
children: []
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我将如何创建一个带有doT.js的模板,该模板将以递归方式遍历对象并构建嵌套列表?
使用递归函数直接在JS中构建html字符串就足够了:(http://jsfiddle.net/fergal_doyle/WN8hZ/5/)
var html = "";
function buildList(a){
if (a.length == 0){return};
html += "<ul>";
for (var i = 0; i < a.length; i++)
{
html += "<li>" + a[i].name;
buildList(a[i].children);
html += "</li>";
}
html += "</ul>";
}
buildList(data.list);
$("#out").html(html);
Run Code Online (Sandbox Code Playgroud)
但是使用doT.js这就是我所拥有的,之后我就难倒了!(http://jsfiddle.net/fergal_doyle/BTZpu/4/)
编辑: 我可以通过混合一些JS与评估(http://jsfiddle.net/fergal_doyle/he8AN/)来做到这一点
{{ function buildList(a) { }}
{{?a.length}}
<ul>
{{~a :v}}
<li>
{{=v.name}}
{{ buildList(v.children); }}
</li>
{{~}}
</ul>
{{?}}
{{ } }}
{{ buildList( it.list ); }}
Run Code Online (Sandbox Code Playgroud)
我试图使用partials来实现它.定义一个ul片段然后让那个片段调用自己作为参数传入一个数组,但是我收到了"太多的递归"错误.如果有任何方法可以使下面的工作,我认为它比上面的更整洁.(http://jsfiddle.net/fergal_doyle/qazGe/4/)
{{##def.ul:a:
<ul>
{{~a :value}}
<li>{{=value.name}}{{#def.ul:value.children}}</li>
{{~}}
</ul>
#}}
{{#def.ul:it.list}}
Run Code Online (Sandbox Code Playgroud)
问题出在编译时。doT.js 似乎没有处理部分递归。您的递归代码{{#def.ul:value.children}}使 doT.js 库无限地解析/将其替换为函数的内容。解决这个问题的一种方法是使用arguments.callee在你的partial中引用你的partial。这是你的FIDDLE的叉子
{{##def.ul:a:
<ul>
{{~a :value}}
<li>{{=value.name}}{{=arguments.callee(value.children)}}</li>
{{~}}
</ul>
#}}
{{#def.ul:it}}
Run Code Online (Sandbox Code Playgroud)
库的作者可以通过以下方式在他们的库中实现相同的想法(未经测试):
function resolveDefs(c, block, def) {
return ((typeof block === 'string') ? block : block.toString())
.replace(c.define || skip, function(m, code, assign, value) {
if (code.indexOf('def.') === 0) {
code = code.substring(4);
}
if (!(code in def)) {
// HANDLE RECURSION START
value = value.replace(c.use || skip, function(m, recursiveCode) {
if (c.useParams) return recursiveCode.replace(c.useParams, function(m, s, d, param) {
if(d == code) {
var ret = s + "{{=arguments.callee(";
if(param)
ret += param;
return ret + ")}}";
}
});
})
// HANDLE RECURSION END
if (assign === ':') {
...
Run Code Online (Sandbox Code Playgroud)