Eliminando el detector de eventos que se agregó con bind
En JavaScript, ¿cuál es la mejor manera de eliminar una función agregada como detector de eventos usando bind()?
Ejemplo
(function(){
// constructor
MyClass = function() {
this.myButton = document.getElementById("myButtonID");
this.myButton.addEventListener("click", this.clickListener.bind(this));
};
MyClass.prototype.clickListener = function(event) {
console.log(this); // must be MyClass
};
// public method
MyClass.prototype.disableButton = function() {
this.myButton.removeEventListener("click", ___________);
};
})();
La única forma que se me ocurre es realizar un seguimiento de cada oyente agregado con bind.
Ejemplo anterior con este método:
(function(){
// constructor
MyClass = function() {
this.myButton = document.getElementById("myButtonID");
this.clickListenerBind = this.clickListener.bind(this);
this.myButton.addEventListener("click", this.clickListenerBind);
};
MyClass.prototype.clickListener = function(event) {
console.log(this); // must be MyClass
};
// public method
MyClass.prototype.disableButton = function() {
this.myButton.removeEventListener("click", this.clickListenerBind);
};
})();
¿Hay alguna manera mejor de hacer esto?
Aunque lo que dijo @machineghost era cierto, que los eventos se agregan y eliminan de la misma manera, la parte que faltaba en la ecuación era esta:
Se crea una nueva referencia de función después de
.bind()
llamarla.
Consulte ¿Bind() cambia la referencia de la función? | ¿Cómo configurarlo permanentemente?
Entonces, para agregarlo o eliminarlo, asigna la referencia a una variable:
var x = this.myListener.bind(this);
Toolbox.addListener(window, 'scroll', x);
Toolbox.removeListener(window, 'scroll', x);
Esto funciona como se esperaba para mí.
Para aquellos que tienen este problema al registrar/eliminar el oyente del componente React hacia/desde la tienda Flux, agregue las siguientes líneas al constructor de su componente:
class App extends React.Component {
constructor(props){
super(props);
// it's a trick! needed in order to overcome the remove event listener
this.onChange = this.onChange.bind(this);
}
// then as regular...
componentDidMount (){
AppStore.addChangeListener(this.onChange);
}
componentWillUnmount (){
AppStore.removeChangeListener(this.onChange);
}
onChange () {
let state = AppStore.getState();
this.setState(state);
}
render() {
// ...
}
}