I’ve written the following and for some reason when I try to remove the item from the collection it’s returning undefined for the item in the removeItem function:
Todos = (function(){
//////////////////////////
//
// MODEL
//
//////////////////////////
var TodoModel = Backbone.Model.extend({
defaults: {
id: null,
item: null
}
});
//////////////////////////
//
// COLLECTION
//
//////////////////////////
var TodoCollection = Backbone.Collection.extend({
model: TodoModel
});
//////////////////////////
//
// VIEW
//
//////////////////////////
var TodoView = Backbone.View.extend({
el: $('#todos'),
itemField: $('#new-item'),
initialize: function(){
this.el = $(this.el);
},
events: {
'submit form': 'addItem',
'click .remove-item': 'removeItem',
// Debug
'click #print-collection': 'printCollection'
},
template: $('#item-template').html(),
render: function(item) {
var templ = _.template(this.template);
var id = _.uniqueId('todo_');
this.el.children('ul').append(templ({id: id,item: item}));
},
addItem: function(e) {
e.preventDefault();
item = this.itemField.val();
// Call render
this.render(item);
// Clear field
this.itemField
.val('')
.focus();
// Add to collection
var newItem = new TodoModel({
item: item
});
this.collection.add(newItem);
},
removeItem: function(e) {
var thisid = this.$(e.currentTarget).parent('li').data("id");
var thisitem = this.collection.get(thisid);
thisitem.remove();
// Remove from DOM
$(e.target).parent('li')
.fadeOut(300,function() {
$(this).remove();
});
},
printCollection: function(){
this.collection.each(function(item) {
console.log(item.get('item'));
});
}
});
//////////////////////////
//
// SELF
//
//////////////////////////
self = {};
self.start = function(){
new TodoView({collection: new TodoCollection()});
};
return self;
});
Models don’t have
removemethods (unless you’ve added one yourself) so this doesn’t work:Models do have
destroymethods though so you could:That will tell the server that the model is gone and the
"destroy"event that it triggers will notify the collection that the model is gone. If you don’t want to talk to the server then you can tell the collection toremovethe model:That will remove it from the collection without bothering the server.
Switching to
this.collection.removeworks: http://jsfiddle.net/ambiguous/8chHf/While I’m here, you have a hidden problem right here:
You’re assigning to the global
self(which is actually a standard property ofwindow) when you probably want to assigning to a local variable calledself. Just this would be sufficient:or you could do it like this if you prefer:
I prefer using
_thisorthatinstead ofselfbecause of the interesting bugs thatwindow.selfcan cause if you forget thevarinvar self;or if you accidentally forget to declareselfat all. And yes, I learned this the hard way.