下划线模板循环,没有循环?

时间:2014-11-18 10:16:42

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

这是从我提出的另一个问题开始的,但我认为这个人试图解释其他问题,或者更可能是我没有解释我的自我权利。

所以我的所有骨干代码都正常工作,并显示输出正确的数据。现在用我的测试数据进行解释,我有17行输入,但即使没有进行 _.each 循环,它的循环也是17次,我只是不明白为什么?

所以我的Backbone代码,

var TimeSheetModel = Backbone.Model.extend({
     defaults: {
        Timesheetrow: "",

     }
}); //End of Timesheet Model

var TimeSheetCollection = Backbone.Collection.extend({
    model: TimeSheetModel,
    url: '/dashboard/jsondata/' + TimesheetID()
}); //End of Timesheet Collection

var TimeSheetView = Backbone.View.extend({
    el:'#testarea', //HTML loading area for the data

    template: _.template( $('#TimesheetData').html() ), //Template to load the JSON data into

    initialize: function(){
      var NewTimeSheetCollection = new TimeSheetCollection(); //New Instance Of Collecttion
      this.listenTo(NewTimeSheetCollection, "add", this.AddMyModel);
      NewTimeSheetCollection.fetch();
    },

    AddMyModel: function(TimeSheetModel) {  //apply model data to view template and append to view element   
       this.$el.append(this.template(TimeSheetModel.toJSON()));
       //$(this.el).html(this.template(TimeSheetRowModel.toJSON()));
    }
}); //End of Timesheet View

//New Instance & render call for the set Timesheet View.
NewTimeSheetVew = new TimeSheetView();
//NewTimeSheetVew.render(); <- do I need this? seems to work, without it?

});

我的Underscore模板代码

<script type="text/template" id="TimesheetData">

<% console.log(Timesheetrow) %>

<% _(1).times(function(n){ n=2;  }); //just a test bit of code %>


 <% if(Timesheetrow.jobtitle) { %>

   <form action="#" method="post" id="TimesheetDataList">

        <div class="TimesheetRowData">
            <input type="hidden" name="data[Timesheetrow][0][id]" value="<%= Timesheetrow.id  %>">
            <input type="type" name="data[Timesheetrow][0][jobtitle]" value="<%= Timesheetrow.jobtitle  %>">
        </div>

    </form>

 <%  }; %>

</script>

所以我的目标是使用骨干,拥有一个主表单,并循环17次(或X,取决于用户给定的行)。所以,例如,我会得到一个输出:

<form id="ID-HERE">
      <div><input value="XXXXX"></div>
      <div><input value="XXXXX"></div>
      <div><input value="XXXXX"></div>
      <div><input value="XXXXX"></div>
      <div><input value="XXXXX"></div>
</form>

但我得到的是循环17次,所以每个输入都是自己的表单标签,所以我目前在页面上有17个表单。

欢迎任何帮助。

请告诉我,如果我没有正确解释自己,我是阅读障碍者,所以我的拼写,语法,可能有点不对,抱歉。

谢谢,

1 个答案:

答案 0 :(得分:2)

您正在侦听集合中的add事件,该事件将在从服务器检索到的每个模型的获取操作之后触发:

this.listenTo(NewTimeSheetCollection, "add", this.AddMyModel);
NewTimeSheetCollection.fetch();

所以你的服务器返回17行,add事件被触发17次,每次你的AddMyModel函数渲染模板。 (如果您查看documentation,则fetch会在内部使用set方法,该方法将触发添加事件。)

您的问题是您用于呈现每个模型的模板包含表单标记,不应该为每个模型重复该表单标记。

你有几种方法可以解决这个问题,基本上要分割一次必须渲染的内容以及每个模型必须呈现的内容:

  • 更新模板以渲染模型数组,在模板内手动循环。不要在集合中监听添加事件,而是将成功回调传递给fetch方法,在fala方法中渲染模板将模型数组传递给它。

  • 将模板拆分为2:带有表单循环的主模板和带有单个TimesheetRow输入的子模板。在视图初始化时渲染主模板,并继续监听集合添加事件。在AddMyModel上,渲染子模板并将其附加到表单中。

  • 将视图拆分为主视图和子视图。主视图将呈现表单并获取集合,侦听添加事件。对于每个添加的模型,它将创建子视图的新实例,向其传递添加的模型,呈现它并在表单中附加el


修改

我使用第三个选项创建了jsfiddle。 有2个观看次数TimeSheetRowViewTimeSheetCollectionView

var TimeSheetRowView = Backbone.View.extend({
    className:'TimesheetRowData', 
    template: _.template($('#TimesheetData').html()), 
    render: function() {
        this.$el.append(this.template(this.model.toJSON()));
        return this.$el;
    }
});

var TimeSheetCollectionView = Backbone.View.extend({
    el:'#MasterContainer', 
    template: _.template($('#TimesheetForm').html()),
    initialize: function(){
        //render master template
        this.$el.append(this.template());
        //keep element so we insert child views before it, inside the form
        this.submitButton = this.$(".actionSubmit"); 
        //initialize collection and listen to events
        this.collection = new TimeSheetCollection();
        this.listenTo(this.collection, "add", this.AddTimesheetRow);

        //simulate a fetch just setting the models
        var hardcodedModels = [{Timesheetrow: {id: 1, index: 0, jobtitle: 'Foo'}},
                              {Timesheetrow: {id: 2, index: 1, jobtitle: 'Bar'}}];
        this.collection.set(hardcodedModels);
    },
    AddTimesheetRow: function(model) {
        //render a single row view and insert it inside the form, right before the submit button
        var view = new TimeSheetRowView({model: model});
        //view.render() returns its $el so we can chain the insertBefore method
        view.render().insertBefore(this.submitButton); 
    }
});

模板分为:

<script type="text/template" id="TimesheetForm">
   <form action="#" method="post" id="TimesheetDataList">   
       <input type="submit" class="actionSubmit" value="Send"/>
   </form>
</script>

<script type="text/template" id="TimesheetData">     
    <input type="hidden" name="data[Timesheetrow][<%= Timesheetrow.index %>][id]" value="<%= Timesheetrow.id  %>">
    <input type="type" name="data[Timesheetrow][<%= Timesheetrow.index %>][jobtitle]" value="<%= Timesheetrow.jobtitle  %>">        
</script>