10

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

2 に答える 2

18

この問題は、Mustache.jsの実装に固有のものです(免責事項:問題が仕様自体にあるかどうかはわかりません)。アルゴリズムは、現在のコンテキストでプロパティが見つからない場合に、親のプロパティを検索します。

簡単に説明すると、コードはテンプレート上で実行され、タグを出力Gar1<ul>して検索します。{{#children}}コンテキストには子タグがあるため、を出力し<li>て、内部コンテキストで実行されるパーシャルを呼び出します{title: 'gar2'}。Mustacheが{{#children}}再びタグに到達すると、現在のコンテキストにchildrenプロパティがないことがわかります。したがって、1レベル上に移動して、実際に子のプロパティを見つけ、狂ったように再び繰り返し始めます(これは本当の言葉ですか?)。

2つの可能な解決策:

1-すべてのエントリにchildrenプロパティが含まれるようにデータを変更し、ノードに子を設定しない場合、falseまたはnull(空の配列ではなく)次のようにします。

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

2-口ひげの代わりにハンドルバーを使用<ul>し、{{#if children}}タグでラップします。

これがお役に立てば幸いです。質問されてから答えが少し遅れていることはわかっています。

于 2012-11-27T20:46:57.943 に答える
5

再帰が必要な 1 つのオブジェクトを次に示します。

物体

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

テンプレート (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>

渡す最初のオブジェクトはルートでありkeyvalue. 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);

Express.js でサーバー側をレンダリングする

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

この例の出力

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

ところで、テンプレートのレンダリングに Hogan.js を使用しています。Mustache.js render が再帰をサポートしているかどうかはわかりません。

于 2013-02-19T20:09:32.437 に答える