4

更新:私のコメントによると、私の問題は、イベントのバインドを解除していないビューに渡す余分なモデルがあることでした。イベント ハンドラーがトリガーされているのを見たとき、this.extra_model がエラー検証にも使用されていることを忘れていたため、ソースは this.extra_model ではなく this.model からのものであると想定しました。

解決策は、以下を追加することでした。

MyView = Backbone.extend({
  //...
  //add method to override BaseView
  cleanUp: function() {
    this.extra_model.off(null, null, this);
    BaseView.prototype.cleanUp.apply(this, arguments);
  },
  //...
});

問題を確認していただきありがとうございます。プログラマーのエラーで申し訳ありません。


すべて: ビューをクリーンアップした後も古い/ゾンビ イベントがバインドされたままになるという問題があります。カスタム イベントをモデルにバインドすると問題が発生します。dom からビューを削除するときは、'this.model.off(null, null, this);' を呼び出します。さまざまなメッセージ ボードで提案されているように、「custom-handler」コールバックが chrome デバッガー ツールで削除されているのを見ることができますが、「custom-handler」のイベント ハンドラーが必要以上に呼び出されていることにまだ気付きます (毎回 1 つ余分にクリーンアップ後にビューを再作成するとき) イベントをトリガーするとき。私のクリーンアップコードに何かが欠けているかどうか誰かに教えてもらえますか? 前もって感謝します!

BaseView = Backbone.extend({
//...
      displayErrors:function(){},

      cleanUp: function(){
        if (this.model) this.model.off(null, null, this);
        if (this.collection) this.collection.off(null, null, this);
        if (!this.options.persistDataAfterViewCleanup) {
          if (this.model) delete this.model;
          if (this.collection) delete this.collection;
        }
        //_.each(this.subViews, function(view){view.cleanUp();}); not needed yet.
        this.undelegateEvents();
        $(this.el).removeData().unbind();
        //Remove view from DOM
        this.$el.html('');
        this.remove();
      }
});

MyView = BaseView.extend({
  initialize: function(){
    //called manually from model using trigger
    this.model.on('custom-handler', this.displayErrors, this);
  }
});
4

1 に答える 1

5

最新バージョンのBackbone(0.9.10)を使用している場合は、新しいBackbone.Events.listenToメソッドを使用してイベントリスナーをバインドする必要があります。このメソッドを使用すると、Backboneはオブジェクトへの参照を保持し、次の場合にすべてのイベントバインディングを自動的にクリアしますview.remove()

this.listenTo(this.model, 'custom-handler', this.displayErrors);

cleanUpメソッドで行うすべてのこと(、、、、、)はdelete、ブードゥープログラミングによく似ています。これらの手順はまったく必要ありません。undelegateEventsremoveDataunbind$el.html('')

ゾンビビューは、直接または間接的に、独自のコードによって保持されているビューへの参照が原因である可能性があります。参照は、イベントハンドラー、バインドされた関数、エクスポートされたクロージャ、または任意の数のものによって保持できます。コードを分析し、Chromeデベロッパーツールのヒーププロファイラーツールを使用して、保持されているオブジェクトとその参照元を見つけてみることをお勧めします。

このSOの質問で私の答えを確認してください。ここでは、特定のコードパスでメモリリークを見つけるための簡単な方法について説明しています。問題はメモリリークに関するものではありませんが、参照のリークに関するものです。参照の保持されているヒープサイズは、それらを保持しているものを見つけるのに役立ちます。

于 2013-03-02T09:35:06.197 に答える