简体   繁体   English

Mustache.js递归

[英]Mustache.js recursion

I am trying to build an html tree using Mustache.js, but it fails throwning an "Maximum call stack size exceeded", probably because an infinite recursion. 我试图使用Mustache.js构建一个html树,但它失败了抛出“超出最大调用堆栈大小”,可能是因为无限递归。

What's wrong? 怎么了?

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);

The problem is inherent to the implementation in Mustache.js (disclaimer: not sure if the problem is in the spec itself) as the algorithm looks for a property on its parent when it can't find it on the current context. 问题是Mustache.js中的实现所固有的(免责声明:不确定问题是否在规范本身中),因为当算法在当前上下文中找不到它时,它会查找其父项的属性。

To explain it briefly: code runs on your template, outputs Gar1<ul> and finds a {{#children}} tag. 简要解释一下:代码在模板上运行,输出Gar1<ul>并找到{{#children}}标签。 Since your context has a children tag it outputs the <li> and invokes the partial which will now run on the inner context {title: 'gar2'} . 由于你的上下文有一个子标记,它输出<li>并调用现在将在内部上下文{title: 'gar2'}上运行的partial。 When Mustache reaches your {{#children}} tag again, it now finds out that the current context has no children property, thus it goes one level up where it actually finds your children property and starts recursing (is this a real word?) again on itself like mad. 当Mustache再次到达你的{{#children}}标签时,它现在发现当前上下文没有children属性,因此它在实际找到你的子属性并开始递归的位置上升一级(这是一个真正的单词吗?)再一次就像疯了似的。

Two possible solutions: 两种可能的解决方

1 - modify your data so that all entries have a children property, and when a node should have no children set it to false or null (not an empty array) like this: 1 -修改您的数据,以便所有条目都具有children属性,当一个节点没有子节点时,将其设置为falsenull (不是空数组),如下所示:

var root = {
    title: 'Gar1',
    children: [{title: 'gar2', children: false}, {title: 'gar3', children: [{title: 'gar4', children: false}]}]
};

2 - use Handlebars instead of Mustache, and wrap the <ul> in an {{#if children}} tag. 2 -使用Handlebars而不是Mustache,并将<ul>包装在{{#if children}}标签中。

Hope this helps, I know the answer is a bit late since this has been asked. 希望这有帮助,我知道答案有点晚,因为有人问过。

Here is one object that needs recursion. 这是一个需要递归的对象。

Object 宾语

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
    }
];

Template (recursion.html). 模板(recursion.html)。

<!-- 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>

The first object you pass in is the root it has no key only a value . 传入的第一个对象是根没有key只有一个value If the value has a property obj set to true then it's an object, print out its key and call the template again recursively for its value. 如果value的属性obj设置为true则它是一个对象,打印出其键并再次递归调用模板以获取其值。 If not an object then no need for recursion, simply print out. 如果不是对象则不需要递归,只需打印出来即可。

Render client side. 渲染客户端。

// 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);

Render server side with Express.js 使用Express.js渲染服务器端

res.render('recursion', {
    value: obj,
    partials: {
        object: 'recursion'
    }
});

Output of this example 此示例的输出

http://jsfiddle.net/simo/GYjMY/ http://jsfiddle.net/simo/GYjMY/

Btw I'm using Hogan.js for rendering the template. 顺便说一句,我正在使用Hogan.js渲染模板。 I don't know whether Mustache.js render supports recursion or not. 我不知道Mustache.js呈现是否支持递归。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM