2012-04-16 146 views
5

我正在使用backbone.js來實現好友列表aka名冊。我對名冊收集和個人rosterEntry骨幹觀點如下:Backbone.js:從集合中刪除項目

Slx.Roster.Views.RosterEntry = Backbone.View.extend({ 
    tagName: "li", 
    className : "rosterEntry clearfix", 
    templateSelector: '#rosterEntryTemplate', 

    initialize: function() { 
     _.bindAll(this, 'render'); 
     this.model.bind('change', this.render); 
     this.model.bind('remove', this.remove); 
     this.template = _.template($("#rosterEntryTemplate").html()); 
    }, 

    remove: function() { 
     debug.log("Called remove event on model"); 
     $(this.el).remove(); 
    }, 
    render: function() { 
     var renderedContent = this.template(this.model.toJSON()); 
     this.id = this.model.Id; 
     $(this.el).attr('id', "friendid-" + this.model.get("id")).html(renderedContent); 
     return this; 
    } 
}); 

    Slx.Roster.Views.Roster = Backbone.View.extend({ 
     el: "div#roster-container", 
     initialize: function() { 
      _.bindAll(this, 'render', 'add', 'remove'); 
      this.template = _.template($("#rosterTemplate").html()); 
      this.collection.bind('reset', this.render); 
      this.collection.bind('add', this.add); 
      this.collection.bind('remove', this.remove); 
     }, 
     add: function (rosterEntry) { 
      var view = new Slx.Roster.Views.RosterEntry(
       { 
        model: rosterEntry 
       }); 
      $(this.el).append(view.render().el); 
     }, 
     remove: function (model) { // if I ommit this then the whole collection is removed!! 
      debug.log("called remomve on collection"); 
     }, 
     render: function() { 
      var $rosterEntries, collection = this.collection; 

      $(this.el).html(this.template({})); 
      $rosterEntries = this.$('#friend-list'); 

      _.each(collection.models, function (model) { 
       var rosterEntryView = new Slx.Roster.Views.RosterEntry({ 
        model: model, 
        collection: collection 
       }); 

       $(this.el).find("ul#friend-list").append(rosterEntryView.render().el); 
      }, this); 

      return this; 
     } 
    }) 

我測試了現在用Firebug控制檯,可以通過執行填充名冊就好了以下內容:

collection = new Slx.Roster.Collection 
view = new Slx.Roster.Views.Roster({collection:collection}) 
collection.fetch() 

添加到收藏也能正常工作,通過執行Firebug控制檯執行以下操作:

collection.add(new Slx.Roster.Model({username:"mickeymouse"})

和新的rosterEntry被添加到名冊。

我的問題是collection.remove(5)從內存集合中刪除,但沒有更新DOM。

奇怪的是,如果我從名冊視圖中刪除remove()函數,名單中的所有條目都將被刪除。如果我在這個方法中沒有任何東西而是添加一個控制檯日誌,它就會調用Roster和RosterEntry視圖中的remove方法 - 雖然我不確定爲什麼,但是它們失靈了!

["Called remove event on model"] 
["called remomve on collection"] 

如果我刪除從RosterEntry模型remove函數我得到這個錯誤:

TypeError: this.$el is undefined 
this.$el.remove(); 

我在做什麼錯?從集合中刪除元素時,如何從元素中刪除元素?

回答

2

我認爲你必須在每一個事件綁定定義context一個問題。

試圖改變這一點:

this.model.bind('remove', this.remove); 

對於這一點:

this.model.bind('remove', this.remove, this); 

我知道你已經嘗試與bindAll來解決這個問題,但bindAll披着每次調用與所列出的方法實際對象的上下文,但如果您在其他對象 :)上調用相同方法,則此操作無法執行任何操作。

更新

我已經閱讀更多..貌似bindAllbind命令的第三paramater做完全一樣的。所以也許你可以使用這個或那個。

因爲是不工作的model.removebindAll是因爲你忘了將它添加到_.bindAll(this, 'render')行,看在你的代碼。我的建議解決了這個問題,因爲我說這兩種方法都是一樣的。

這一切都做的是確保該所列出的方法(render, remove, ...在一種情況下或this.remove的除外)的調用是要去interpretate this作爲實際對象的引用。這看起來很笨,但this非常易在JS中易變

不要擔心,如果你仍然與this的事情混淆,我已經處理了很長時間,仍然not completely cofindent

也許essais like this可以幫助我們。

+1

你是什麼意思我有每個evenet綁定定義的問題?不知道我真的很明白什麼樣的行爲是對你誠實的。我只是認爲所有事件都必須添加到綁定。 – reach4thelasers 2012-04-16 20:49:30

+0

綁定函數的第三個參數代表什麼? – reach4thelasers 2012-04-16 22:07:03

+0

這工作!謝謝!認爲我已經通過閱讀另一個stackoverflow帖子瞭解bindall是什麼,但爲什麼沒有綁定所有的工作?它似乎做同樣的事情....也爲什麼我不需要在集合綁定語句額外的'這個'? – reach4thelasers 2012-04-17 08:04:16

-1

這兩個視圖的remove方法可能被調用,因爲你已經綁定在模型和集合上刪除。

在RosterEntry:

this.model.bind('remove', this.remove); 

在名冊:

this.collection.bind('remove', this.remove); 
+0

這不是我已經得到的嗎? – reach4thelasers 2012-04-16 20:51:21

0

您是否嘗試過以下方法?

this.listenTo(this.model, "remove", this.remove); 

這似乎適用於我,我喜歡它的方式讀得好一點。

Link to Backbone doc