20

今回は、イベントをバインドするさまざまな方法に苦労しています。私は自分のコードで言及されたすべてのメソッドを持っています。私が正しい道を進んでいるかどうかはわかりません。変更後にビューが完全に閉じられていることを確認するために、常に bindTo を使用する必要があります (現時点では、これによりエラーが発生することがよくあります)。正しい方向に進むのに役立つベスト プラクティスはありますか?

マリオネットについての私の現在の理解を説明するために、ここに私のアプリの 1 つのモジュールを示します。いつものように、すべてのヒントは大歓迎です。

PP.module('Grid', function(Grid, PP, Backbone, Marionette, $, _){

  Grid.Product = Backbone.Model.extend({});

  Grid.ProductCollection = Backbone.Collection.extend({
    model: Grid.Product,
    url: '/products/query'
  });

  Grid.ProductView = Backbone.Marionette.ItemView.extend({
    className: 'grid',
    template: 'public/templates/grid-template'
  });

  // Helper Methods
  // -----------------------

  var getGenderCode = function(genderName){
    var genderMap = {
      'men': 'M',
      'women': 'W',
      'unisex': 'A'
    }

    return genderMap.genderName;
  }

  // Public API
  // -------------------

  Grid.renderGrid = function(productCollection){
    Grid.productView = new Grid.ProductView({
      collection: productCollection
    });

    Grid.productView.bind('show', function(){
      $('#isotope-container').isotope({
        itemSelector : '.item',
        containerStyle: {
          position: 'relative',
          zIndex: 1
        }
      });
    });

    PP.Layout.mainRegion.show(Grid.productView);
  }

  // Event Handlers
  // -----------------------

  PP.vent.bind('grid:requested', function(categoryData){
    // use bootstrapped data on first start
    if (PP.App.bootstrappedCategoryName !== categoryData.categoryName) {
      Grid.productCollection.fetch({
        data: {
          gender: getGenderCode(categoryData.categoryName),
          category: categoryData.categoryId
        }
      });
    }
    else {
      PP.vent.trigger('mainview:ready', {
        categoryName: PP.App.bootstrappedCategoryName
      });
    }
  });

  // Initializer
  // --------------------

  PP.addInitializer(function(options){
    Grid.productCollection = new Grid.ProductCollection();

    Grid.productCollection.on('reset', function(){
      Grid.renderGrid(Grid.productCollection);
    });

    Grid.productCollection.reset(options.newArrivalsList);
  });
});
4

1 に答える 1

34

一般的なガイドラインとして、アプリケーションの存続期間中に作成および破棄されるオブジェクトがあり、そのオブジェクトを他のオブジェクトからのイベントにバインドする必要がある場合は、EventBinder.

ビューとメモリ リーク

ビューはこの完璧な例です。ビューは常に作成され、破棄されます。modelまた、ビューとビューの両方からのさまざまなイベントにバインドしcollectionます。ビューが破棄されると、それらのイベントをクリーンアップする必要があります。ビューで組み込みbindToメソッドを使用すると、イベント ハンドラーがクリーンアップされます。使用せずに直接bindTo使用する場合は、ビューが閉じられた/破棄されたときにon手動で呼び出してイベントのバインドを解除する必要があります。offそうしないと、ゾンビ (メモリ リーク) が発生します。

まだ読んでいない場合は、次の記事をご覧ください。

http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

http://lostechies.com/derickbailey/2012/03/19/backbone-js-and-javascript-garbage-collection/

カスタム イベント グループ

ただし、これが適用されるのはビューだけではなく、 の唯一の使用例でもありませんEventBinder

少数のオブジェクトを操作してそれらのイベントにバインドし、それらのオブジェクトを他のオブジェクト インスタンスに置き換えることができる場合は、EventBinderが役立ちます。この場合、EventBinder は、関連するオブジェクトのイベントのコレクションまたはグループと考えてください。

ObjA、ObjB、および ObjC があるとします。これらのそれぞれがいくつかのイベントを発生させ、コードが完了したらイベント ハンドラーを確実にクリーンアップする必要があります。これは簡単EventBinderです:



doStuff = {

  start: function(a, b, c){
    this.events = new Marionette.EventBinder();
    this.events.bindTo(a, "foo", this.doSomething, this);
    this.events.bindTo(b, "bar", this.anotherThing, this);
    this.events.bindTo(c, "baz", this.whatever, this);
  },

  doSomething: function(){ /* ... */ },
  anotherThing: function(){ /* ... */ },
  whatever: function(){ /* ... */ },

  stop: function(){
    this.events.unbindAll();
  }

}

doStuff.start(ObjA, ObjB, ObjC);

// ... some time later in the code, stop it

doStuff.stop();

このコードを呼び出すstopと、この使用のためにすべてのイベント ハンドラーが適切にクリーンアップされます。

いつ使用するonか/off直接

これとは逆に、常に . を使用する必要はありませんEventBinder。いつでも、それなしで逃げることができます。ただし、必要に応じてイベントをクリーンアップすることを忘れないでください。

イベント ハンドラーをクリーンアップする必要がない状況では、 も使用する必要はありませんEventBinder。これは、ルーターがトリガーするイベント、またはMarionette.Applicationオブジェクトがトリガーするイベントである可能性があります。これらのアプリケーション ライフサイクル イベント、またはアプリの存続期間全体にわたって存在する必要があるイベントについては、EventBinder. 代わりに、イベント ハンドラーを存続させてください。ユーザーがブラウザー ウィンドウを更新するか、別のサイトに移動すると、その時点でハンドラーがクリーンアップされます。

しかし、メモリとイベント ハンドラーを管理する必要がある場合は、参照をクリーンアップし、ページを更新したりページから移動したりせずにページを閉じることが、EventBinderイベント管理を簡素化するために重要になります。

于 2012-08-06T22:11:15.867 に答える