【问题标题】:When to use bindTo, bind or on with Backbone.Marionette?何时使用 bindTo、绑定或与 Backbone.Marionette 一起使用?
【发布时间】:2012-07-31 19:17:12
【问题描述】:

这一次我正在为绑定事件的不同方法而苦苦挣扎。我的代码中有所有提到的方法。我只是不知道,如果我走对了。也许我应该总是使用 bindTo 来确保我的视图在更改后完全关闭(目前这通常会产生错误)?是否有任何最佳实践可以帮助我朝着正确的方向前进?

为了说明我目前对 Marionette 的理解,这是我的应用程序中的一个模块。一如既往,非常欢迎每一个提示。

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

【问题讨论】:

  • 看起来 bindTo 在 1.4 中不再有效,但在 0.9 版本中有效。最好使用 bind 代替。

标签: backbone.js marionette


【解决方案1】:

一般准则是,当您有一个对象在应用程序的整个生命周期中被创建和销毁,并且该对象需要绑定到来自其他对象的事件时,您应该使用EventBinder

视图和内存泄漏

视图就是一个很好的例子。视图一直被创建和销毁。它们还绑定到视图上modelcollection 的许多不同事件。当视图被销毁时,需要清理这些事件。通过在视图上使用内置的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 变得很重要,因为它简化了事件管理。

【讨论】:

  • 我在您的博客文章中读到过类似的内容,但对我来说,您具体而详细的回答更能说明问题。非常感谢!
  • 感谢 Derek,非常有帮助的解释。
  • 你提到开/关,但没有明确提到'bind()'。 bind 只是另一种表示开/关的方式吗?他的例子显示了绑定,所以我有点困惑为什么你的详细回复没有提到它。 (编辑:好吧,我会的 - 他们是同一件事:stackoverflow.com/questions/11847021/jquery-bind-vs-on
猜你喜欢
  • 1970-01-01
  • 2013-11-12
  • 2015-05-15
  • 2013-06-18
  • 1970-01-01
  • 2019-08-22
  • 2016-08-07
  • 2020-01-11
  • 2015-04-16
相关资源
最近更新 更多