Reputation: 1357
I am trying to remove a jQuery event who's callback is bound with this
. The problem is that .bind()
creates a new function every time... so when I try removing the event, it is technically not the same function so it doesn't work.
I can't figure out how to keep the right this
inside the callback in this case:
class Controller {
open() {
$('body').on('click', this.handleClick.bind(this));
}
close() {
$('body').off('click', this.handleClick.bind(this));
}
}
Upvotes: 1
Views: 139
Reputation: 35481
Do the binding once in the constructor.
class Controller {
constructor() {
// overwrite handleClick() with its bound version
this.handleClick = this.handleClick.bind(this);
}
open() {
$('body').on('click', this.handleClick);
}
close() {
$('body').off('click', this.handleClick);
}
}
This way you overwrite the function once with the bound version that refers to the proper this
and then attach/detach that function in your methods.
The additional advantage of doing things this way is that the binding is done only once, during instantiation, and then any future calls to open()
or close()
will use the same function that has the proper this
.
Upvotes: 1
Reputation: 33870
jQuery has its own .bind
polyfill. You can use $.proxy()
to do what you want since it keep internaly a GUI. You can then unbind using the original function. jQuery is brillant enough:
class Controller {
open() {
$('body').on('click', $.proxy(this.handleClick, this));
}
close() {
$('body').off('click', this.handleClick);
}
}
Here an article that demonstrate it : http://www.bennadel.com/blog/2001-using-jquery-s-proxy-method-in-event-binding-and-unbinding.htm
jQuery keeps an internal counter to represent a "guid" (Globally Unique ID). When a function goes through the proxy() method, jQuery generates a new guid value and then applies that guid to both the core function as well as the resultant proxy function. It does this so that you can use the original function reference to unbind an event handler callback that has been proxied - jQuery uses the guid to test for function equivalence during the unbind process.
To see it in action, just explore this fiddle : https://jsfiddle.net/Lfqq88uj/1/
Upvotes: 1
Reputation: 12452
You can simply use jQuery namespaces:
class Controller {
open() {
$('body').on('click.myNamespace', this.handleClick.bind(this));
}
close() {
$('body').off('click.myNamespace');
}
}
Upvotes: 2