在underscore.js模板引擎中的模板(递归)中运行模板

时间:2011-11-09 15:30:08

标签: javascript templates backbone.js underscore.js

我使用backbone.js和underscore.js来构建一个javascript应用程序。由于阅读和尝试在下面的模板中运行模板的时间很长,因此越来越令人沮丧。

我的模板使用undercore.js模板引擎构建:

<script id="navigation_template" type="text/template">
  <div><%= title %>
      <% _.each(children, function(child) { %>
          <% render_this_template_recursively(child) %>
      <% }); %>
  </div>
</script>

我想为每个子元素渲染此模板(render_this_template_recursively(child))。

我该怎么做?

由于

4 个答案:

答案 0 :(得分:36)

我个人没试过这个,但是_.template会返回一个函数(我将它命名为templateFn以强调它),所以你可以将它传递给模板,如下所示:

var templateFn = _.template($('#navigation_template').html());

$(this.el).html(templateFn({model: this.model, templateFn: templateFn}));

请注意,我正在传递整个模型(假设您的模型有一个子属性,它本身就是骨干模型的集合),您的模板将更改为:

<script id="navigation_template" type="text/template">
  <div><%= model.escape('title') %>
      <% _.each(model.children, function(child) { %>
          <%= templateFn(child, templateFn) %>
      <% }); %>
  </div>
</script>
祝你好运。我希望这对你有用

答案 1 :(得分:5)

我尝试使用timDunham和Ates Goral提供的示例,但它对我不起作用,所以我对它做了一点升级。在下面找到它。

视图:

    template: _.template($("#tree").html()),

    render: function () {
        this.$el.html(this.template({
            options: this.collection.toJSON(),
            templateFn: this.template
        }));
    }

和模板:

<script type="text/template" id="tree">
<ul>
    <% _.each(options, function (node) { %>
        <li><%= node.title %></li>
        <% if (node.children) { %>
            <%= templateFn({ options: node.children, templateFn: templateFn }) %>
        <% } %>
    <% }); %>
</ul>

它对我来说非常好。正如您所看到的,主要区别在于将配置对象传递给templateFn,而不是参数。希望你会发现它很有用。

答案 2 :(得分:1)

递归模板可能如下所示:

<ul>
    <% entries.forEach(function (entry) { %>
    <li>
        <%= entry.title %>
        <%
        if (entry.children) {
            print(tmpl({
                entries: entry.children,
                tmpl: tmpl
            }));
        }
        %>
    </li>
    <% }); %>
</ul>

首先,预编译您的模板:

entriesTmpl = _.template(entriesTmpl);

然后在传递数据和模板本身时调用它:

$el.html(entriesTmpl({
    entries: entryTree,
    tmpl: entriesTmpl
});

答案 3 :(得分:0)

我最近使用骨干关系实现了这一点。如果你想看到一个可行的解决方案,我创建了一个我认为可能有帮助的小提琴:http://jsfiddle.net/blaisco/ADKrK/

我已在下面发布了相关内容。

观点:

var FolderView = Backbone.View.extend({
    el: $("#main"),

    template: _.template($("#folder-tmpl").html()),

    render: function () {
        this.$el.html(this.template({
            "folder": parentFolder.toJSON(),
            "templateFn": this.template
        }));
        return this;
    }
});

html / template:

<ul id="main"></ul>

<script type="text/template" id="folder-tmpl">
    <li>
        <a href="#" class="folder"><%= folder.title %></a>
        <% if(folder.children.length) { %><ul><% } %>
        <% _.each(folder.children, function(child) { %>
            <%= templateFn({"folder": child, "templateFn": templateFn}) %>
        <% }); %>
        <% if(folder.children.length) { %></ul><% } %>
    </li>
</script>