这是从我提出的另一个问题开始的,但我认为这个人试图解释其他问题,或者更可能是我没有解释我的自我权利。
所以我的所有骨干代码都正常工作,并显示输出正确的数据。现在用我的测试数据进行解释,我有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个表单。
欢迎任何帮助。
请告诉我,如果我没有正确解释自己,我是阅读障碍者,所以我的拼写,语法,可能有点不对,抱歉。
谢谢,
答案 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个观看次数TimeSheetRowView
和TimeSheetCollectionView
:
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>