我在使用教程时遇到问题
this.collection.bind('add',appendItem)
和
this.collection.bind('add',appendSet)
appendItem 是一个在backbone.js 视图中为视图集合定义的函数。appendSet 也一样问题是我想通过嵌套模型来扩展教程,但是当我添加一个项目时,如果我使用上面的行,我已经将 appendItem 和 appendSet 绑定到 add 函数,所以 add 函数赢了不知道这应该是什么。
(快速提醒一下 bind 的作用:http ://underscorejs.org/#bind )
那我还怎么用
this.collection.add(thisItem)
并且仍然避免绑定问题。简而言之:有没有办法调用 this.collection.add(thisItem) 并告诉 add 函数关键字 'this' 应该引用 appendItem 而不使用绑定函数?
如果需要,我可以包含我的代码,但我认为它有点长且笨拙,而且可能无论如何都没有用。
编辑:
我的代码的逻辑是这样的。项目是具有多个属性的模型以及与其相关联的集合的集合。我只是在学习一个教程,他让这些对象呈现的方式是他使用 this.collection.bind('add',appendItem) 以便当您调用 this.collection.add 时,会调用 appendItem。这是 appendItem 的代码:
appendItem: function(item){
alert("append exercise called in allExerciseview");
var itemView=new ItemView({
model: Item
});
$('ul',this.el).append(itemView.renderItem().el);
}
我找不到 this.collection.add 的源代码,但我假设在该函数中有 this 是指 appendItem 调用 appendItem 函数。简而言之:原因是这段代码:
this.collection.bind('add',appendItem)
这样当你打电话时
this.collection.add(thisItem)
它也运行
thisItem.appendItem()
解除绑定并仅运行 this.collection.add(thisItem) 然后单独运行 thisItem.appendItem() 对我不起作用。
我的示例代码:
(function($){
Backbone.sync = function(method, model, success, error) {
success();
};
var Set = Backbone.Model.extend({
defaults: {
SetName:"Set "
//more properties...
},
initialize: function(){
alert("you've created a new set");
this.bind("error",function(model,error){
alert(error);
});
}
});
var SetCollection = Backbone.Collection.extend({
model:Set
});
var SetView = Backbone.View.extend({
events: {
'click button.deleteSet': 'removeSet'
},
initialize: function(){
alert('initialize called in setview');
_.bindAll(this,'renderSet', 'unrenderSet', 'removeSet');
/*this.model.bind('change',this.renderSet);
this.model.bind('remove',this.unrender); Not sure if I should do this*/
return this; //apparently for chainable calls
},
renderSet: function(){
alert('renderset called in setview');
$(this.el).html('a set template'); //add button after so you can test delete
return this;
},
unrenderSet: function(){
alert('unrenderset called in setview');
$(this.el).remove();
},
removeSet: function(){
alert('removeset called in setview');
this.model.destroy();
}
});
var AllSetView = Backbone.View.extend({
el: $('body'), //el attaches to existing element <-- what does this mean?
events: {
'click button#addSetButton': 'addSet'
},
initialize: function(){
alert('initialize called in allsetview');
_.bindAll(this,'renderAllSet', 'addSet', 'appendSet');
this.collection = new SetCollection();
this.collection.bind('add', this.appendSet); // Problem here...
this.counter = 0;
this.renderAllSet();
},
renderAllSet: function(){
alert('renderallset called in allsetview');
var self = this;
$(this.el).append('<button id="addSetButton"> Add Set </button>');
$(this.el).append('<ul></ul>');
_(this.collection.models).each(function(set){ //in case collection is not empty
self.appendSet(set);
},this);
},
addSet: function(){
alert('addSet called in allsetview');
this.counter++;
var thisSet = new Set();
thisSet.set({SetName:thisSet.get('SetName')+this.counter});
this.collection.add(thisSet); //add is a function defined for the collection
},
appendSet: function(item){
alert("append set called in allsetview");
var setView = new SetView({
model: Set //DO NOT CAPITALIZE!!!... or do capitalize?... ack
});
$('ul',this.el).append(setView.renderSet().el);
}
});
var allsetview = new AllSetView(); //for testing
var Item = Backbone.Model.extend({
defaults: {
ItemName: 'Enter an Item'
//more properties
},
initialize: function(){
alert('youve created a new item');
var set1 = new Set();
var setCollection = new SetCollection([set1]);
this.set({sets:setCollection});
this.bind("error",function(model,error){
alert(error);
});
}
});
var ItemCollection = Backbone.Collection.extend({
model:Item
});
var ItemView = Backbone.View.extend({
events: {
'click button.deleteItem': 'removeItem'
},
initialize: function(){
alert('initialize called in itemview');
_.bindAll(this,'renderItem', 'unrenderItem', 'removeItem');
//this.model.bind('change',this.renderItem);
//this.model.bind('remove',this.unrender); Not sure if I should do this
return this; //apparently for chainable calls
},
renderItem: function(){
alert('renderitem called in Itemview');
$(this.el).html('an item template'); //add button after so you can test delete
return this;
},
unrenderItem: function(){
alert('unrenderitem called in itemview');
$(this.el).remove();
},
removeItem: function(){
alert('removeItem called in itemview');
this.model.destroy();
}
});
alert ("before itemview creation");
var itemview = new ItemView();
alert ("now after");
var AllItemView = Backbone.View.extend({
el: $('body'), //el attaches to existing element <-- what does this mean?
events: {
'click button#addItemButton': 'addItem'
},
initialize: function(){
alert('initialize called in allitemview');
_.bindAll(this,'renderAllItem', 'addItem', 'appendItem');
this.collection = new ItemCollection();
this.collection.bind('add', this.appendItem); //Problem here
this.counter = 0;
this.renderAllItem();
},
renderAllItem: function(){
alert('renderallitem called in allitemview');
var self = this; //why
$(this.el).append('<button id="addItemButton"> Add Item </button>');
$(this.el).append('<ul></ul>');
_(this.collection.models).each(function(item){ //in case collection is not empty
self.appendItem(item);
},this); //what is this function
},
addItem: function(){
alert('addItem called in allitemview');
this.counter++;
var thisItem = new Item();
thisItem.item({ItemName:thisItem.get('ItemName')+this.counter
});
this.collection.add(thisItem); //add is a function defined for the collection
this.appendItem(thisItem);
},
appendItem: function(item){
alert("append item called in allItemview");
var itemView = new ItemView({
model: Item //DO NOT CAPITALIZE!!!... or do capitalize?...
});
$('ul',this.el).append(itemView.renderItem().el);
}
});
})(jQuery);