Javascript 为什么当我单击X时,所有项目都会从我的Backbone.js视图中删除

Javascript 为什么当我单击X时,所有项目都会从我的Backbone.js视图中删除,javascript,dom,backbone.js,Javascript,Dom,Backbone.js,js。我想知道为什么当我点击相册和艺术家旁边的X时,我的backbone.js会同时删除这两个项目 i、 e The Chronic-- Dr. Dre-- X Ten-- Pearl Jam-- X 我很感激我能得到的任何反馈,使我只删除一个项目,而不是两个项目 JavaScript: (function($){ Backbone.sync = function(method, model, success, error){ success(); } //Declare mod

js。我想知道为什么当我点击相册和艺术家旁边的X时,我的backbone.js会同时删除这两个项目

i、 e

The Chronic-- Dr. Dre-- X
Ten-- Pearl Jam-- X
我很感激我能得到的任何反馈,使我只删除一个项目,而不是两个项目

JavaScript:

(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);
(函数($){
Backbone.sync=函数(方法、模型、成功、错误){
成功();
}
//声明模型
var Album=Backbone.Model.extend({
默认值:{
专辑:《逻辑程序第1卷》,
艺术家:'LTJ Bukem'
}
});
//申报集合
var eList=Backbone.Collection.extend({
型号:相册
});
//声明相册的视图
var AlbumView=Backbone.View.extend({
el:$('div#main'),
模板:\ u0.template(
" " +  
"   -- " +
"   -- " +
“X”+
""
),
事件:{
'单击span.delete':'删除相册'
},  
初始化:函数(){
_.bindAll(这是“渲染”、“取消渲染”、“删除相册”);
this.model.bind('remove',this.unender);
},
//`unnder()`:使模型从DOM中删除自身。
unender:function(){
这个。$el.remove();
},
deleteAlbum:function(){
this.model.destroy();
},
render:function(){
$(this.el).append(this.template(this.model.toJSON());
}
});
var appendItem=函数(项目){
var albumView=新建albumView({
型号:项目
});
albumView.render();
}
////启动工作
var elist=新elist();
bind(“add”,函数(listItem){appendItem(listItem)});
添加({
专辑:《慢性病》,
艺术家:“Dre博士”
});
添加({
专辑:《十》,
艺术家:《珍珠酱》
});
})(jQuery);

有几件事我可以指出

首先,您的视图-当您为每个相册创建多个实例时-每个实例共享相同的el。也就是说,div#main。每次添加一个模板时,都会将模板内容附加到el中,这就是为什么仍然可以看到另一个模板的原因。但当您单击.delete并执行this.$el.remove()时,您正在删除el中的所有内容。其中包括另一个视图

你应该把它分开,每个视图都应该有自己独特的el

el: 'div',
className: 'albumView'
添加每个相册视图时,可以创建视图并将其附加到div#main中

这将使每个视图对其自己的el保持满意,删除只会影响该视图/模型/DOMELENT

UPDATE-context of
$('#main').append(view.render().el)

基本上,当您创建相册视图并附加它们时,最理想的方法是在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对僵尸视图的看法,并实现一个
close()
方法,该方法将
remove()
unbind()
您的视图,因此没有对它的引用,并且可以对其进行垃圾收集。不是这个问题的重点,但有助于获得额外的学分,而且可能与此相关,因为这可能会使您的代码更加复杂:-P


有几件事我可以指出

首先,您的视图-当您为每个相册创建多个实例时-每个实例共享相同的el。也就是说,div#main。每次添加一个模板时,都会将模板内容附加到el中,这就是为什么仍然可以看到另一个模板的原因。但当您单击.delete并执行this.$el.remove()时,您正在删除el中的所有内容。其中包括另一个视图

你应该把它分开,每个视图都应该有自己独特的el

el: 'div',
className: 'albumView'
添加每个相册视图时,可以创建视图并将其附加到div#main中

这将使每个视图对其自己的el保持满意,删除只会影响该视图/模型/DOMELENT

UPDATE-context of
$('#main').append(view.render().el)

基本上,当您创建相册视图并附加它们时,最理想的方法是在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对僵尸视图的看法,并实现一个
close()
方法,该方法将
remove()
unbind()
您的视图,因此没有对它的引用,并且可以对其进行垃圾收集。不是这个问题的重点,但有助于获得额外的学分,而且可能与此相关,因为这可能会使您的代码更加复杂:-P


谢谢orangewrap,但是$('#main').append(view.render().el)中的el指的是什么,c指的是什么