自发现Ractivejs以来,我正在慢慢将我的应用程序转移到它上面。
在使用 Vanilla JavaScript构建html树结构来创建元素之前,请在完成后将其附加到页面上。我最近将它移到了Ractivejs上,它与一个小的树结构一起很好地工作,但是如果涉及到一个深度嵌套的对象,它将超出调用堆栈。
有没有一种方法可以将我在JavaScript中建立的元素附加到Ractivejs模板上并保留Ractivejs事件,还是有一种在不超出调用堆栈的情况下递归遍历大对象的方法?
例子
用JavaScript构建树的方式
var tree = {
'childPages' : [{
'name': 'first child',
'childPages': []
}, {
'name': 'second child',
'childPages': [{
'name': 'second first sub child',
'childPages': []
}]
}, {
'name': 'third child',
'childPages': [{
'name': 'third first sub child',
'childPages': [{
'name': 'sub sub child',
'childPages': []
}]
}]
}]
};
function buildTree (tree) {
var ul = document.createElement('ul');;
for(var i =0; i < tree.childPages.length; i++){
var li = document.createElement('li');
li.innerText = tree.childPages[i].name;
ul.appendChild(li);
if (tree.childPages[i].childPages.length) {
li.appendChild (buildTree(tree.childPages[i]));
}
}
return ul;
}
document.body.appendChild(buildTree(tree));
如何在Ractivejs模板中构建树
var ractive = new Ractive({
el : 'body',
template: '#treeNode',
data: {
'childPages' : [{
'name': 'first child',
'childPages': []
}, {
'name': 'second child',
'childPages': [{
'name': 'second first sub child',
'childPages': []
}, {
'name': 'second second sub child',
'childPages': []
}]
}, {
'name': 'third child',
'childPages': [{
'name': 'third first sub child',
'childPages': [{
'name': 'sub sub child',
'childPages': []
}]
}]
}]
}
});
<script src="http://cdn.ractivejs.org/latest/ractive.js"></script>
<script id="treeNode" type="text/ractive">
<ul>
{{#each childPages}}
<li>
{{name}}
{{#if childPages}}
{{> treeNode}}
{{/if}}
</li>
{{/each}}
</ul>
</script>
最佳答案
通常,当您超出调用堆栈时,这是因为Ractive处理丢失的数据属性的方式-如果您有{{with foo}}{{bar}}{{/with}}
而foo.bar
不存在,则{{bar}}
引用将无法解析,因此它“进入上下文堆栈”,而是寻找bar
。
在大多数情况下,这确实很方便,但是在这种情况下可能会出现问题,因为如果树中的某个项目没有childPages
属性,Ractive就会将栈上移到父级-这会将我们带入无限递归兔子洞。
有两种解决方案:
childPages
属性,即使它是一个空数组,也可以... this.childPages
而不是childPages
(或./childPages
-这是等效的,则您可能会比较喜欢另一种),那么Ractive不会在当前上下文之外查找数据。这是一个示例,删除了所有空的childPages
数组-没有this.
,我们立即超过了调用堆栈,但是因为它在那里,所以我们完全安全。 var ractive = new Ractive({
el : 'body',
template: '#treeNode',
data: {
'childPages' : [{
'name': 'first child'
}, {
'name': 'second child',
'childPages': [{
'name': 'second first sub child'
}, {
'name': 'second second sub child'
}]
}, {
'name': 'third child',
'childPages': [{
'name': 'third first sub child',
'childPages': [{
'name': 'sub sub child'
}]
}]
}]
}
});
<script src="http://cdn.ractivejs.org/latest/ractive.js"></script>
<script id="treeNode" type="text/ractive">
<ul>
{{#each this.childPages}}
<li>
{{name}}
{{#if this.childPages}}
{{> treeNode}}
{{/if}}
</li>
{{/each}}
</ul>
</script>