js. I would like to know why my backbone.js is removing both items when I click on the X next to the album and artist.
i.e.
The Chronic-- Dr. Dre-- X
Ten-- Pearl Jam-- X
I appreciate any feedback that I could get that would allow me to only remove one item as opposed to both
Javacript:
(function($){
Backbone.sync = function(method, model, success, error){
success();
}
//Declare model
var Album = Backbone.Model.extend({
defaults: {
album: 'Logical Progresions vol. 1',
artist:'LTJ Bukem'
}
});
//Declare collection
var eList = Backbone.Collection.extend({
model: Album
});
//Declare the view for the Albums
var AlbumView = Backbone.View.extend({
el: $('div#main'),
template: _.template(
"<div class=\"alert\"> " +
" <span class=\"album\"><%= album %>--</span> " +
" <span claas=\"artist\"><%= artist %>--</span> " +
" <span class =\"delete\">X</span> " +
"</div>"
),
events: {
'click span.delete': 'deleteAlbum'
},
initialize: function(){
_.bindAll(this, 'render','unrender','deleteAlbum');
this.model.bind('remove', this.unrender);
},
// `unrender()`: Makes Model remove itself from the DOM.
unrender: function(){
this.$el.remove();
},
deleteAlbum: function(){
this.model.destroy();
},
render: function(){
$(this.el).append(this.template(this.model.toJSON()));
}
});
var appendItem = function(item){
var albumView = new AlbumView({
model: item
});
albumView.render();
}
//// set the stuff in motion
var elist = new eList();
elist.bind("add",function(listItem){appendItem(listItem)});
elist.add({
album: 'The Chronic',
artist: 'Dr. Dre'
});
elist.add({
album: 'Ten',
artist: 'Pearl Jam'
});
})(jQuery);
There are a few things I can point out.
First, your view – when you create multiple instances for each album – each share the same el. That is, div#main. Each time you add one, you’re appending the template stuff to the el which is why you still see the other. But when you click on .delete and execute the this.$el.remove() you are removing everything in the el. Which includes the other view.
You should separate it out, each view should have it’s own unique el.
When you add each album view, you can create the view and append it to your div#main
This should keep each view happy with its own el and removal will only affect that view/model/DOMelement.
UPDATE – context of
$('#main').append(view.render().el);Basically, when you create the albumViews and append them the most ideal place to do this is in the larger context in which your div#main exists. For example, this might happen in your main js script in the header, or maybe even in a larger view that contains many albumView subviews. To illustrate the subview context:
You might also want to store reference to those subviews by adding these lines in your code of the parent view. It will make cleaning up easier although it’s not a big deal if you intend on cleaning up individual views through the subviews themselves.
Hope this helps.
PS – Last note that I noticed. When you remove a view, I noticed you use
remove()which is the way to get it out of the DOM. If you’re making more complex subviews intertwined/tangled with event listeners to collections, models, and other views – you might want to read Derick Bailey’s take on Zombie views and implementing aclose()method that will bothremove()andunbind()your view so there are no references to it and it can be garbage collected. Not the focus of this question but good for extra credit and possibly relevant since this has probably made your code more complicated. 😛Removing Views – avoiding zombies