您有一个包含id
,parentid
和message
属性的项目列表。 parentid
引用同一列表中的其他项。嵌套级别没有限制。你会如何实现这个?
换句话说,如何采取这个:
var data = [
{
id: 1,
parentid: 0,
message: "I'm 1, and I have no parent."
}, {
id: 2,
parentid: 1,
message: "I'm 2, and 1 is my parent."
}, {
id: 3,
parentid: 1,
message: "I'm 3, and 1 is my parent."
}, {
id: 4,
parentid: 0,
message: "I'm 4, and I have no parent."
}, {
id: 5,
parentid: 1,
message: "I'm 5, and 2 is my parent."
}
];
把它变成这个:
<ul>
<li>
I'm 1, and I have no parent.
<ul>
<li>
I'm 2, and 1 is my parent.
<ul>
<li>
I'm 5, and 2 is my parent.
</li>
</ul>
</li>
<li>
I'm 3, and 1 is my parent.
</li>
</ul>
</li>
<li>
I'm 4, and I have no parent.
</li>
</ul>
在模板中如何做到这一点有一个很好的快速方法吗?没有遍历整个数组,构建一个新数组,并渲染它?
甚至比什么是模板的最佳实现是递归渲染自己直到什么都没有留下?
答案 0 :(得分:2)
使用ractive.js,您可以使用javascript使用部分和表达式帮助函数来过滤数组(有关完整示例,请参阅http://jsfiddle.net/pUf5P/1/)
模板:
{{# { index: 0 } }}
{{>lister}}
{{/ }}
<!-- {{>lister}} -->
<ul>
{{# filter(list, .index) }}
<li>{{message}}
{{# { index: id } }}
{{>lister}}
{{/ }}
</li>
{{/ }}
</ul>
<!-- {{/lister}} -->
设定:
new Ractive({
el: 'body',
template: '#template',
data: {
list: data,
filter: function(list, parent){
return list.filter(function(item){
return item.parentid === parent
})
}
}
})
或者对于纯模板解决方案(请参阅http://jsfiddle.net/pUf5P/2/),您可以执行以下操作:
{{# { index: 0 } }}
{{>lister}}
{{/ }}
<!-- {{>lister}} -->
<ul>
{{#list}}
{{# .parentid === index}}
<li>{{message}}
{{# { index: .id } }}
{{>lister}}
{{/ }}
</li>
{{ /}}
{{/list }}
</ul>
<!-- {{/lister}} -->
更新:我知道你想要这样做“没有遍历整个数组,建立一个新的”,但是意识到你在每个级别循环遍历整个数组以找到匹配的子节点。您不需要构建层次结构,只需根据父ID进行存储(参见http://jsfiddle.net/pUf5P/3/):
var byParent = {}
data.forEach(function(item){
if(!byParent[item.parentid]){ byParent[item.parentid] = [] }
byParent[item.parentid].push(item)
})
然后使用上述模板策略的变体:
{{# { index: 0 } }}
{{>lister}}
{{/ }}
<!-- {{>lister}} -->
<ul>
{{# { list: byParent[index]} }}
{{#list}}
<li> {{(.message)}}
{{# { index: .id } }}
{{>lister}}
{{/ }}
</li>
{{/list}}
{{/ }}
</ul>
<!-- {{/lister}} -->