0

js。我想知道为什么当我单击专辑和艺术家旁边的 X 时,我的主干.js 会删除这两个项目。

IE

The Chronic-- Dr. Dre-- X
Ten-- Pearl Jam-- X

我很感激我能得到的任何反馈,这将允许我只删除一个项目,而不是两个

Java脚本:

(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);
4

1 回答 1

3

有几点我可以指出。

首先,您的视图 - 当您为每个相册创建多个实例时 - 每个实例共享相同的 el。也就是说,div#main。每次添加一个时,您都会将模板内容附加到 el 中,这就是您仍然看到另一个的原因。但是当您单击 .delete 并执行 this.$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 感到满意,并且删除只会影响该视图/模型/DOM 元素。

更新 - 的上下文$('#main').append(view.render().el);

基本上,当您创建专辑视图并附加它们时,最理想的位置是在您的 div#main 存在的更大上下文中。例如,这可能发生在标题中的主 js 脚本中,或者甚至可能发生在包含许多专辑视图子视图的更大视图中。为了说明子视图上下文:

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()which 将其从 DOM 中取出。如果您正在制作更复杂的子视图与集合、模型和其他视图的事件侦听器交织/纠缠 - 您可能想阅读 Derick Bailey 对 Zombie 视图的看法并实现一种close()方法,该方法将remove()unbind()您的视图相结合,因此没有参考它可以被垃圾收集。不是这个问题的重点,但有利于获得额外的荣誉并且可能相关,因为这可能会使您的代码更加复杂。:-P

删除视图 - 避免僵尸

于 2012-08-30T00:41:32.130 回答