0

js. アルバムとアーティストの横にある X をクリックすると、backbone.js が両方のアイテムを削除する理由を知りたいです。

すなわち

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

両方を削除するのではなく、1 つのアイテムのみを削除できるようなフィードバックをいただければ幸いです。

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

1 に答える 1

3

私が指摘できることがいくつかあります。

まず、ビュー (アルバムごとに複数のインスタンスを作成する場合) は、それぞれが同じ el を共有します。つまり、div#main です。1つを追加するたびに、テンプレートのものをelに追加しているため、もう1つが表示されます。しかし、.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 要素にのみ影響します。

UPDATE - のコンテキスト$('#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()。それとそれはガベージコレクションすることができます。この質問の焦点では​​ありませんが、コードをより複雑にする可能性があるため、追加のクレジットに適している可能性があります。:-Premove()unbind()

ビューの削除 - ゾンビの回避

于 2012-08-30T00:41:32.130 に答える