Backbone js .listenTo vs .on

Chr*_*nch 66 backbone.js

以下2行代码有哪些优缺点?我不明白为什么有两种不同的方法来做同样的事情.

this.listenTo(app.Todos, 'change:completed', this.filterOne);
app.Todos.on('change:completed', this.filterOne);
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*ons 118

listenTo是更新更好的选项,因为这些侦听器将自动为您移除,在stopListening此期间,当视图被删除(通过remove())时调用.之前listenTo有一个非常隐蔽的问题,幻影视图永远存在(泄漏内存并导致错误行为),因为视图方法在模型上被引用为事件侦听器,即使视图实例本身已经很久没有在DOM中了.

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

至于默认上下文,有几件事最终可以绑定到this:

  • 如果你进行绑定this.listenTo,它将始终是视图实例(Wim Leers在评论中指出)
  • 没有this.listenTo,故事变得复杂
    • 对于misc事件,它将是全局对象(最好避免这种情况)
    • 对于DOM事件,它将像常规DOM事件绑定一样成为源元素
    • 如果你提供一个显式的上下文(第三个参数foo.on),骨干将使用它(因此这是一个更健壮的方法)
    • 如果您使用ECMA标准function () {//your event handler}.bind(this),您也可以手动控制上下文(也推荐)
    • 正如@mu指出的那样,_.bind或者$.proxy是ECMA的替代品function.bind
    • 对于骨干视图,当任何视图方法用作事件处理程序时,操作this.bindAll('onClick', ...)将确保视图实例是this上下文
  • 通过使用视图的标准events属性连接的任何事件将通过主干自动绑定到视图实例(这是腰带和吊带bindAll)

所以总结一些指导方针:

  • events尽可能使用该属性,因为它简洁明了
  • 使用this.listenTo所有绑定模型和集合
  • 任何其他绑定都记得使用您的首选方法可靠地绑定上下文.我通常使用ECMA,Function.bind因为嘿,标准,但这里有几个不错的选择.

  • 请注意,使用`listenTo`时*不能*设置显式上下文; 它始终是`listenTo`是一个方法的对象.没有第四个论点. (9认同)
  • @NickBarrett`app.Todos.on('change:completed',this.filterOne.bind(<specific_context>));`或`this.listenTo(app.Todos,'change:completed',this.filterOne.bind( <specific_context>));` (2认同)