ChatGPT解决这个技术问题 Extra ChatGPT

Backbone js .listenTo vs .on

What are the advantages and disadvantages of the following 2 lines of code? I don't understand why there are 2 different ways to do the same thing.

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

Also when using .on, how do I determine is the default context?


P
Peter Lyons

listenTo is the newer and better option because these listeners will be automatically removed for you during stopListening which is called when a view gets removed (via remove()). Prior to listenTo there was a really insidious problem with phantom views hanging around forever (leaking memory and causing misbehavior) because view methods were referenced as event listeners on models even though the view instances themselves were long gone and no longer in the DOM.

If you want to read the back story for listenTo, search the backbone github repository for listenTo and read through some of the longer issue discussions.

As to the default context, several things can end up bound to this:

if you do the binding via this.listenTo, it will always be the view instance (pointed out by Wim Leers in the comments)

without this.listenTo, the story gets complicated For misc events, it will be the global object (best to avoid this) for DOM events, it will be the source element just like in regular DOM event binding If you provide an explicit context (the 3rd argument to foo.on), backbone will use that (thus this is a more robust approach) If you use the ECMA standard function () {//your event handler}.bind(this), you can also manually control the context (also recommended) As @mu pointed out, _.bind or $.proxy are available alternatives to ECMA function.bind For backbone views, doing this.bindAll('onClick', ...) will ensure the view instance is the this context when any view methods are used as event handlers

For misc events, it will be the global object (best to avoid this)

for DOM events, it will be the source element just like in regular DOM event binding

If you provide an explicit context (the 3rd argument to foo.on), backbone will use that (thus this is a more robust approach)

If you use the ECMA standard function () {//your event handler}.bind(this), you can also manually control the context (also recommended)

As @mu pointed out, _.bind or $.proxy are available alternatives to ECMA function.bind

For backbone views, doing this.bindAll('onClick', ...) will ensure the view instance is the this context when any view methods are used as event handlers

any events wired up by using the view's standard events property will get bound for you automatically to the view instance by backbone (this is belt & suspenders with bindAll)

So to summarize into some guidelines:

use the events property whenever possible as it is concise and correct

use this.listenTo for all bindings to models and collections

any additional bindings remember to bind the context reliably using your preferred method. I usually use ECMA Function.bind because hey, standards, but there are several good options here.


There's also _.bind and $.proxy if you don't want to (or can't) use ECMA's bind.
I came across jasmine-headless-webkit apparently complaining about ECMA's bind, with "undefined is not a function", though the jasmine suite passed in the browser. I switched to using Underscore's bindAll.
Note that you cannot set an explicit context when using listenTo; it's always the object that listenTo is a method on. There is no fourth argument.
If we need to set a specific context, can you give an example of an alternative?
@NickBarrett app.Todos.on('change:completed', this.filterOne.bind(<specific_context>)); or this.listenTo(app.Todos, 'change:completed', this.filterOne.bind(<specific_context>));
E
Emile Bergeron

With listenTo, the object whose events you want to listen to is passed as the first argument. In the case of on, it is actually a method on that object.

The advantages of listenTo over on are:

The listener keeps track of all the event handlers, making it easier to remove them all at once when needed.

The callback’s context is always set to the listener itself.


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

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now