ChatGPT解决这个技术问题 Extra ChatGPT

骨干 js .listenTo 与 .on

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

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

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


P
Peter Lyons

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

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

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

如果您通过 this.listenTo 进行绑定,它将始终是视图实例(Wim Leers 在评论中指出)

没有 this.listenTo,故事会变得复杂对于 misc 事件,它将是 DOM 事件的全局对象(最好避免这种情况),它将是源元素,就像在常规 DOM 事件绑定中一样如果您提供显式上下文( foo.on 的第三个参数),主干将使用它(因此这是一种更健壮的方法)如果您使用 ECMA 标准函数 () {//您的事件处理程序}.bind(this),您还可以手动控制上下文(也推荐)正如@mu 指出的那样, _.bind 或 $.proxy 是 ECMA function.bind 的可用替代品 对于主干视图,执行 this.bindAll('onClick', ...) 将确保视图实例是 this任何视图方法用作事件处理程序时的上下文

对于杂项事件,它将是全局对象(最好避免这种情况)

对于 DOM 事件,它将是源元素,就像在常规 DOM 事件绑定中一样

如果您提供明确的上下文(foo.on 的第三个参数),主干将使用它(因此这是一种更强大的方法)

如果使用ECMA标准函数(){//你的事件处理程序}.bind(this),也可以手动控制上下文(也推荐)

正如@mu 指出的那样, _.bind 或 $.proxy 是 ECMA function.bind 的可用替代品

对于主干视图,当任何视图方法用作事件处理程序时,执行 this.bindAll('onClick', ...) 将确保视图实例是 this 上下文

使用视图的标准事件属性连接的任何事件都将通过主干自动绑定到视图实例(这是带有 bindAll 的腰带和吊带)

所以总结为一些指导方针:

尽可能使用 events 属性,因为它简洁正确

对模型和集合的所有绑定使用 this.listenTo

任何其他绑定都记得使用您的首选方法可靠地绑定上下文。我通常使用 ECMA Function.bind,因为嘿,标准,但这里有几个不错的选择。


如果您不想(或不能)使用 ECMA 的 bind,还有 _.bind$.proxy
我遇到 jasmine-headless-webkit 显然在抱怨 ECMA 的 bind,“未定义不是函数”,尽管 jasmine 套件在浏览器中传递。我改用下划线的bindAll
请注意,您在使用 listenTo不能设置显式上下文;它始终是 listenTo 是一个方法的对象。没有第四个论点。
如果我们需要设置一个特定的上下文,你能举一个替代的例子吗?
@NickBarrett app.Todos.on('change:completed', this.filterOne.bind(<specific_context>));this.listenTo(app.Todos, 'change:completed', this.filterOne.bind(<specific_context>));
E
Emile Bergeron

使用 listenTo,您想要监听其事件的对象作为第一个参数传递。在 on 的情况下,它实际上是该对象上的一个方法。

listenTo 优于 on 的优点是:

侦听器会跟踪所有事件处理程序,以便在需要时更轻松地一次性删除它们。

回调的上下文始终设置为侦听器本身。


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅