Cant detach functions from events via the off() API method (ES6)
Cant detach functions from events via the off() API method (ES6)
jLinux
Posts: 981Questions: 73Answers: 75
I was able to attach a static function to events via the on()
, and it works fine. But I'm having issues detaching the event using the off()
method. Ive tried a few different variations of the off()
method with no success.
Heres the JS ES6 class with the methods used to attach/detach the function and event, as well as the actual function that gets attached/detached
class myPlugin{
constructor (dtSettings){
this._dtApi = new $.fn.dataTable.Api( dtSettings );
this._dtSettings = dtSettings;
dtSettings.oMyPlugin = this;
}
attach(){
var eventParams = {
dtSettings: this._dtSettings,
dtApi: this._dtApi
};
this._dtApi.on( 'draw.dt', eventParams, myPlugin.event.bind( myPlugin ) );
}
detach(){
var eventParams = {
dtSettings: this._dtSettings,
dtApi: this._dtApi
};
// None of the following seem to work..
this._dtApi.off( 'draw.dt', eventParams, myPlugin.event.bind( myPlugin ) );
this._dtApi.off( 'draw.dt', myPlugin.event.bind( myPlugin ) );
this._dtApi.off( 'draw.dt', eventParams, myPlugin.event );
this._dtApi.off( 'draw.dt', myPlugin.event );
}
static event(e){
var { dtSettings, dtApi } = e.data;
alert('Triggered draw.dt for table ID #'+dtSettings.sTableId);
}
}
And heres how that class is getting used
((window, document, $, undefined) => {
$( document ).on( 'init.dt', ( e, dtSettings ) => {
new myPlugin( dtSettings );
});
$.fn.dataTable.Api.register( 'myPlugin.attach()', function ( ) {
return this.iterator( 'table', function ( dtSettings ) {
return dtSettings.oMyPlugin.attach();
} );
} );
$.fn.dataTable.Api.register( 'myPlugin.detach()', function ( ) {
return this.iterator( 'table', function ( dtSettings ) {
return dtSettings.oMyPlugin.detach();
} );
} );
})(window, document, jQuery);
Any help would be appreciated
This question has accepted answers - jump to:
This discussion has been closed.
Answers
The issue is that
myPlugin.event.bind
is returning a new function each time you call it. So what in effect is happening is:Since the off line doesn't match anything, nothing is removed (events are a bu**er this way - that's way just about every events library there is wraps the calling function up into its own closure that it can keep track off).
There are two options:
.dt
namespace - you can add another custom one as you can then just remove all events by passing in that event.namespace without a function.There might be some other magic ES6 way of doing it (using a fat arrow for example), but I'm not sure.
Allan
I think option #2 would be my preferred route...
How would using a closure help though? Heres what ive tried this far: http://jsfiddle.net/2e09qzjo/2/
Sorry I didn't explain that very well! Your closure would be assigned to a variable somewhere so it can be accessed again when required. It doesn't need to be an anonymous function like that - the result from
bind
could be used, but the key is that if you want to pass the function tooff
you need to pass the original function that was added - not a duplicate of it.Allan
Hm.. this might be a little tricky. I guess i could store the function in a closure in dtSettings. Ill try!
Namespaces are the way forward :-)
You mean attaching them to
draw.dt.something
? Hm.. I suppose I could do something likedraw.dt.${table_id}
or something..This needs to work with multiple tables, meaning I cant just detach everything from
draw
, or else it will do it for all tables.Well actually, since the events are via the API, which is specific to the table, I suppose I dont have to use the table ID...
This seems to work :)
Lines #15 and #41