2012-04-16 17 views
5

私はbackbone.jsを使ってRosterというバディリストを実装しています。次のように名簿の収集および個々の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モデルから削除機能を削除した場合、私はこのエラーを取得する:

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

は私が間違って何をしているのですか?コレクションから削除されたDOMから要素を削除するにはどうすればよいですか?

答えて

2

私はあなたがすべてのイベントのバインド定義でcontextに問題があると思います。私はあなたがbindAllでこれを解決しようとしたけど、bindAllはと記載されているメソッドにすべての呼び出しをラップしている

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

:このため

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

は、これを変更するようにしてください他のオブジェクト :)でと同じメソッドを呼び出す場合、これは何もできません。

私は...多くを読んでいる

を更新しましたがbindAllのように見えるとbindコマンドの第三のparamaterは正確に同じことを行います。だから多分あなたはどちらか一方を使うことができます。

model.removebindAllに動作していないので、あなたのコードで見て、_.bindAll(this, 'render')ラインに追加するのを忘れたためです。と私は両方のアプローチが同じことを言っているので、私の提案はそれを修正しました。

何このすべてが記載された方法(他の1つの場合はrender, remove, ...またはthis.remove)への呼び出しは、実際のオブジェクトへの参照としてinterpretate thisつもりであることを保証されてやっています。これは愚かに見えるかもしれませんが、thisはJSで非常にvolatileです。

まだthisのものと混同していても構わないと思いますが、私はそれを長く扱っていますが、まだnot completely cofindentです。

多分essais like thisがお手伝いします。

+1

すべてのEvenetバインド定義に問題があるとはどういう意味ですか?私は本当にあなたに正直であるためにbindallが何であるかを理解していません。私はちょうどすべての出来事がbindallに加えられなければならないと思った。 – reach4thelasers

+0

バインド関数の3番目のパラメータは何を表していますか? – reach4thelasers

+0

これがうまくいった!ありがとう!私は別のstackoverflowのポストを読むことによってbindallが何のためにsussedだと思うが、なぜbindallの仕事をしなかったのですか?それは同じことをするように思われる....なぜ私はコレクションのバインドステートメントに余分な 'this'を必要としないのですか? – reach4thelasers

-1

モデルとコレクションの両方で削除するように設定されているため、両方のビューのremoveメソッドが呼び出されている可能性があります。 RosterEntryで

:名簿で

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

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

これは私がすでに持っているものではありませんか? – reach4thelasers

0

あなたは次のことを試しましたか?

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

私にとってはうまくいくと思われますが、私は少し上手く読む方法が好きです。

Link to Backbone doc

関連する問題