JS。我想知道为什么当我点击专辑和艺术家旁边的X时,我的backbone.js正在删除这两个项目。
即。
The Chronic-- Dr. Dre-- X
Ten-- Pearl Jam-- X
我感谢我能得到的任何反馈,这样我只能删除一个项目而不是两个项目
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);
答案 0 :(得分:3)
我可以指出一些事情。
首先,您的视图 - 当您为每个专辑创建多个实例时 - 每个实例共享相同的el。也就是说,div#main。每次添加一个,你都会将模板内容添加到el中,这就是为什么你仍然会看到另一个。但是当你点击.delete并执行这个。$ el.remove()你将删除el中的所有内容。其中包括另一种观点。
你应该把它分开,每个视图应该有它自己独特的el。
el: 'div',
className: 'albumView'
添加每个相册视图时,您可以创建视图并将其附加到div#main
var view = new AlbumView();
$('#main').append(view.render().el); // the el refers to the subview (albumView) el.
这应该让每个视图都对自己的el感到满意,删除只会影响该视图/ model / DOMelement。
更新 - $('#main').append(view.render().el);
基本上,当您创建albumViews并附加它们时,最理想的位置是在div #main存在的较大上下文中。例如,这可能发生在标题中的主js脚本中,或者甚至可能发生在包含许多albumView子视图的较大视图中。为了说明子视图上下文:
var ParentView = Backbone.View.extend({
el: $('#main'),
render: function() {
this.addAllAlbums(); // On rendering the parent view, we add each album subview
return this;
},
addAllAlbums: function() {
var self = this;
// This loops through the collection and makes a view for each album model
this.collection.each(function(albumModel) {
self.addAlbumView(albumModel);
});
},
addAlbumView: function(albumModel) {
var view = new AlbumView({
'model': albumModel
});
// We are adding/appending each albumView to this view's el
this.$el.append(view.render().el);
// ABOVE: `this.$el` refers to ParentView el. view.render().el refers to the
// albumView or subview el.
// As explained before, now each album view has it's own el which exists in
// the parent view's this.el = `$('#main')`
}
});
// We create the parent BIG/ALLAlbumsView and toss into it the collection of albums
var BigAlbumsView = new ParentView({
'collection': albumsCollection
});
BigAlbumsView.render(); // Run the `render()` to generate all your album subviews
您可能还希望通过在父视图的代码中添加这些行来存储对这些子视图的引用。如果您打算通过子视图本身清理个人视图,这将使清理变得更容易。
// In your initialization, we create an array to store album subviews
this.albumViews = [];
// In `addAlbumView()` we push each view into the array so we have a reference
this.albumViews.push(view);
// When cleaning up, you just simply cycle through the subviews[] and remove/close
// each album subview
_.each(this.albumViews, function(albumView) {
albumView.$el.remove();
});
希望这有帮助。
PS - 最后注意到我注意到了。当您删除视图时,我注意到您使用remove()
这是将其从DOM中删除的方法。如果您正在将更复杂的子视图与事件监听器交织在一起,与集合,模型和其他视图交织在一起 - 您可能希望阅读Derick Bailey对Zombie视图的看法并实现close()
方法remove()
}和unbind()
您的视图因此没有对它的引用,它可以被垃圾收集。不是这个问题的焦点,但有利于额外的功劳和可能相关,因为这可能使您的代码更复杂。 :-P