Backbone.js 主干js.listenTo vs.on

Backbone.js 主干js.listenTo vs.on,backbone.js,Backbone.js,以下两行代码的优缺点是什么?我不明白为什么有两种不同的方法来做同一件事 this.listenTo(app.Todos, 'change:completed', this.filterOne); app.Todos.on('change:completed', this.filterOne); 另外,在使用.on时,如何确定默认上下文?listenTo是更新更好的选项,因为这些侦听器将在停止侦听期间为您自动删除,当视图被删除时(通过remove()调用)。在listenTo之前,幻影视图一直存

以下两行代码的优缺点是什么?我不明白为什么有两种不同的方法来做同一件事

this.listenTo(app.Todos, 'change:completed', this.filterOne);
app.Todos.on('change:completed', this.filterOne);

另外,在使用.on时,如何确定默认上下文?

listenTo
是更新更好的选项,因为这些侦听器将在
停止侦听期间为您自动删除,当视图被删除时(通过
remove()
调用)。在
listenTo
之前,幻影视图一直存在一个非常隐秘的问题(内存泄漏并导致错误行为),因为视图方法被引用为模型上的事件监听器,即使视图实例本身早已不在DOM中

如果您想阅读
listenTo
的背景故事,请在github主干存储库中搜索
listenTo
,并通读一些较长的问题讨论

至于默认上下文,有几件事最终可能会绑定到此

  • 如果您通过
    this.listenTo
    进行绑定,它将始终是视图实例(由Wim Leers在注释中指出)
  • 如果没有
    this.listenTo
    ,故事就会变得复杂
    • 对于杂项事件,它将是全局对象(最好避免此情况)
    • 对于DOM事件,它将是源元素,就像在常规DOM事件绑定中一样
    • 如果您提供了一个明确的上下文(
      foo.on
      )的第三个参数),主干网将使用该上下文(因此这是一种更健壮的方法)
    • 如果使用ECMA标准
      函数(){//your event handler}.bind(this)
      ,还可以手动控制上下文(也推荐使用)
    • 正如@mu所指出的,
      .bind
      $.proxy
      是ECMA
      函数.bind
    • 对于主干视图,当任何视图方法用作事件处理程序时,执行
      this.bindAll('onClick',…)
      将确保视图实例是
      this
      上下文
  • 使用视图的标准
    events
    属性连接的任何事件将通过主干自动绑定到视图实例(这是带
    bindAll
    的皮带和吊杆)
因此,总结为一些指导原则:

  • 尽可能使用
    事件
    属性,因为它简洁正确
  • 对模型和集合的所有绑定使用
    this.listenTo
  • 任何其他绑定都要记住使用首选方法可靠地绑定上下文。我通常使用ECMA
    Function.bind
    ,因为嘿,是标准,但这里有几个不错的选择

使用
listenTo
,要侦听其事件的对象将作为第一个参数传递。对于上的
,它实际上是该对象上的一个方法

listenTo
on
的优点是:

  • 侦听器跟踪所有事件处理程序,以便在需要时一次删除所有事件处理程序

  • 回调的上下文总是设置为侦听器本身


如果您不想(或不能)使用ECMA的
bind
,也有。我遇到了
jasmine headless webkit
,显然是在抱怨ECMA的
bind
,带有“undefined不是一个函数”,尽管jasmine套件在浏览器中传递。我切换到使用下划线的
bindAll
。请注意,使用
listenTo
时不能设置显式上下文;
listenTo
始终是方法所在的对象。没有第四个参数。如果我们需要设置一个特定的上下文,您能给出一个替代的例子吗?@NickBarrett
app.Todos.on('change:completed',this.filterOne.bind())
this.listenTo(app.Todos,'change:completed',this.filterOne.bind())