在Backbone.js中填充嵌套的下划线模板

时间:2014-03-26 10:43:28

标签: templates backbone.js views underscore.js underscore.js-templating

我正在尝试从复杂的JSON对象创建一个html页面。我已经成功地将JSON对象解析为模型集合,其中每个模型都有另一个模型的集合等。

因此,我有嵌套视图以满足此需求。

要创建我的html页面,我有两个模板,如下所示:

<script type="text/template" id="template1">
        <h1><%=heading1%></h1>
        <h2><%=heading2%></h2>

        <ul id="template2-list"></ul>
</script>

<script type="text/template" id='template2'>
    <p class = "heading"><%-otherheading%></p>

<div class="content" id="tab">

    .....

</div>
</script>

如您所见,我有一个模板(template1),其中包含template2列表。我如何从Backbone嵌套视图中填充这些模板?

这就是我的尝试:

var CollectionView = Backbone.View.extend({

    type: "CollectionView", //For debugging purposes

    el: "#container", 

    initialize: function () {

    },

    render: function () {
        _.each(this.model.models, this.process, this);
        return this;
    },

    process: function(obj)
    {
        var childItemView = new View1({model: obj});
        childItemView.render();
        this.$el.append(childItemView.el); //This works fine since I only have one Model in the highest level collection
    }

})

var View1 = Backbone.View.extend({

    type: "View1",

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

    tagName: "div",
    className: "tableRow",

    initialize:function () {
        this.model.on("change", this.modelChanged, this);
    },

    render: function () {

        var outputHtml = this.template(this.model.toJSON());
        this.$el.html(outputHtml);

        this.model.get('nestedModel').each(this.process, this);

        return this;
    },

    process: function(obj) {

        var childItemView2 = new View2({model: obj});
        childItemView2.render();   

        childItemView2.el = '#template2-list';

        $(this.el).append(childItemView2.el); //This still results in template2 being placed after the entire template 1

    },

    modelChanged: function(model, changes) {
        console.log("modelChanged: " + this.model.get('title'));
    }

});

3 个答案:

答案 0 :(得分:1)

如果它只是填充下划线,那么你应该将集合转换为json(包括子模型集合),并且可以在模板内添加for循环。 &lt;%for(var x ...%&gt;。

另一个选择是,要使用像marionette这样的库,它具有可以保存集合视图的复合视图,您可以在此处查看treeView的示例:http://lostechies.com/derickbailey/2012/04/05/composite-views-tree-structures-tables-and-more/ 它基本上展示了如何在集合中呈现集合。

答案 1 :(得分:1)

有很多方法可以做到这一点。

模板内的模板

传递整个集合,并通过调用父模板本身内的子模板,在模板本身中执行所有递归迭代逻辑。只涉及一种观点。

 <script type="text/template" id="template1">
    <h1><%=heading1%></h1>
    <h2><%=heading2%></h2>
    <ul id="template2-list">
       <!-- Your iteration logic goes here -->
       <%= _.template($("#template2").html())({model: model}) %>
    </ul>
 </script>
 <script type="text/template" id='template2'>
     <p class = "heading"><%-otherheading%></p>
     <div class="content" id="tab"></div>
 </script>

更好的方法是:

  • 在集合视图中,创建一个子视图实例(您已经完成了)

  • 执行递归迭代逻辑以读取集合视图(parentview)中的集合模型,并调用子视图以呈现子集合。

如果你想要一个完整的解决方案,请用json和html创建一个小提琴。将帮助您使其发挥作用。

答案 2 :(得分:1)

我意识到自己的错误。不确定这是否完全正确,但我首先渲染了父视图,然后找到了新的列表元素(template2-list)并将渲染的子视图附加到该视图。

即。

render: function () {

    var outputHtml = ...

    this.$el.html(outputHtml); //render parent view

    this.model.get('nestedModel').each(this.process, this);

    ...
},

process: function(obj) {

    var childItemView2 = new View2({model: obj});
    childItemView2.render();   

    this.$('#template2-list').append(childItemView2.el); 

},

感谢您的帮助!