[英]Recursion with 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: []
}
]
}
]
}
我將如何創建一個帶有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);
但是使用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 ); }}
我試圖使用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}}
問題出在編譯時。 doT.js似乎沒有在partials中處理遞歸。 遞歸代碼{{#def.ul:value.children}}
使doT.js庫無限地解析/替換函數的內容。 解決此問題的一種方法是使用arguments.callee來引用部分內部的部分。 這是你的FIDDLE的一個分支
{{##def.ul:a:
<ul>
{{~a :value}}
<li>{{=value.name}}{{=arguments.callee(value.children)}}</li>
{{~}}
</ul>
#}}
{{#def.ul:it}}
圖書館的作者可以通過以下方式在他們的圖書館中實現相同的想法(未經測試):
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 === ':') {
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.