I have problem with Backbone's events system.
Is it possible to pass jquery function as callback directly?
Following code does not fire show/hide methods:
initialize: function () {
this.render();
this.logoutButton = $('#logout-button');
this.logoutButton.hide();
this.listenTo(this.model, 'loginSuccessEvent', this.logoutButton.show);
this.listenTo(this.model, 'logoutSuccessEvent', this.logoutButton.hide);
},
But if I change it to this, it works perfectly:
initialize: function () {
this.render();
this.logoutButton = $('#logout-button');
this.logoutButton.hide();
this.listenTo(this.model, 'loginSuccessEvent', this.showButton);
this.listenTo(this.model, 'logoutSuccessEvent', this.hideButton);
},
showButton: function () {
this.logoutButton.show();
},
hideButton: function () {
this.logoutButton.hide();
}
From the fine manual:
listenTo
object.listenTo(other, event, callback)
[...]
Thecallback
will always be called withobject
as context.
So when you say this:
this.listenTo(this.model, 'loginSuccessEvent', this.logoutButton.show);
you're really saying:
var show = this.logoutButton.show;
this.listenTo(this.model, 'loginSuccessEvent', show);
And then Backbone will call show
more or less like this:
your_view.show(arg, ...);
// Or internally:
show.apply(your_view, arguments);
so when show
(which is jQuery's show
) gets called, its this
will be your view rather than logoutButton
. Remember that this
inside a JavaScript function depends on how the function is called rather than where it is defined (except for bound functions of course).
You have some options:
Use your showButton
and hideButton
functions.
Use an anonymous function:
this.listenTo(this.model, 'loginSuccessEvent', function() {
this.logoutButton.show();
});
Use a bound function:
this.listenTo(this.model, 'loginSuccessEvent', this.logoutButton.show.bind(this.logoutButton));
Careful with this though, show
will be called with the arguments that listenTo
would normally use so you might need to supply more arguments to bind
to avoid confusing show
and hide
with arguments they're not expecting.