我正在尝试使用Mustache.js构建一个html树,但它无法抛出“超出最大调用堆栈大小”,可能是因为无限递归。
怎么了?
var Mustache = require('mustache');
var root = {
title: 'Gar1',
children: [{title: 'gar2'}, {title: 'gar3', children: [{title: 'gar4'}]}]
};
var panelTemplate = '{{title}}<ul>{{#children}}<li>{{>panel}}</li>{{/children}}</ul>';
var partials = {panel: panelTemplate};
var output = Mustache.render(panelTemplate, root, partials);
console.log(output);
答案 0 :(得分:18)
问题是Mustache.js中的实现所固有的(免责声明:不确定问题是否在规范本身中),因为当算法在父上找不到属性时在当前背景下找到它。
简要解释一下:代码在您的模板上运行,输出Gar1<ul>
并找到{{#children}}
标记。由于您的上下文有一个子标记,它会输出<li>
并调用现在将在内部上下文{title: 'gar2'}
上运行的部分。当Mustache再次到达你的{{#children}}
标签时,它现在发现当前上下文没有children
属性,因此它在实际找到你的children属性并开始递归的位置上升一级(这是真的这个词?)就像疯了一样。
两种可能的解决方案:
1 - 修改您的数据,以便所有条目都具有children
属性,当节点没有子节点时,将其设置为false
或null
(不是空数组)像这样:
var root = {
title: 'Gar1',
children: [{title: 'gar2', children: false}, {title: 'gar3', children: [{title: 'gar4', children: false}]}]
};
2 - 使用Handlebars而不是Mustache,并将<ul>
包裹在{{#if children}}
标记中。
希望这有帮助,我知道答案有点晚了,因为有人问过。
答案 1 :(得分:5)
这是一个需要递归的对象。
var obj = [
{
obj: true,
key: 'a',
value: [
{
obj: false,
key: 'a',
value: 1
},
{
obj: false,
key: 'b',
value: 2
},
{
obj: true,
key: 'c',
value: [
{
obj: false,
key: 'a',
value: 3
}
]
}
]
},
{
obj: false,
key: 'b',
value: 4
}
];
<!-- root -->
<ul>
{{#value}}
<li>
<!-- object -->
{{#obj}}
<span><b>{{key}}</b></span>
{{>object}}
{{/obj}}
<!-- value -->
{{^obj}}
<span><b>{{key}}</b> <span>{{value}}</span></span>
{{/obj}}
</li>
{{/value}}
</ul>
您传入的第一个对象是没有key
的根只有value
。如果value
将属性obj
设置为true
,那么它就是一个对象,打印出其密钥并再次递归调用模板以获取其值。
如果不是对象则不需要递归,只需打印出来。
// html is recursion.html contents
var template = Hogan.compile(html),
content = template.render({value: obj}, {object: html});
// show the rendered template
$('body').empty().append(content);
res.render('recursion', {
value: obj,
partials: {
object: 'recursion'
}
});
顺便说一句,我正在使用Hogan.js渲染模板。我不知道Mustache.js渲染是否支持递归。