Peter
Peter

Reputation: 620

How to properly unbind jQuery window event handler in Ember component

I know that the best practice for binding an event handler to a window event with jQuery is

jQuery(window).on('resize', Ember.run.bind(this, this.handleResize));

If you try to unbind the event handler though in willDestroyElement with

$(window).off('resize', this.handleResize);

this doesn't work because .on() and .off() must be called with the exact same reference to the handler function.

But also the following does not work:

$(window).off('resize', Ember.run.bind(this, this.handleResize));

So the only option I can think off to make sure my event handler does not get called after the component was destroyed is something like this:

willDestroyElement: function () {
  this.set('handleResize', null);
}

...as suggested in this stackoverflow question. But this is not really a proper unbinding. Any suggestions?

Upvotes: 1

Views: 959

Answers (1)

Piotr
Piotr

Reputation: 860

Your option is to either namespace the event like this:

jQuery(window).on('resize.handleResize', Ember.run.bind(this, this.handleResize));

and then use:

$(window).off('resize.handleResize');

to unbind the event (without providing the function). Here is more about event namespacing: https://css-tricks.com/namespaced-events-jquery/

The other way would be to save the reference to the function like this:

...
this.set('boundResizeHandler', Ember.run.bind(this, this.handleResize))
jQuery(window).on('resize', this.get('boundResizeHandler'));
...

and then unbind it like this:

$(window).off('resize', this.get('boundResizeHandler')

As to why $(window).off('resize', Ember.run.bind(this, this.handleResize)); didn't work. Every time you call Ember.run.bind(this, this.handleResize) it creates a new function. So the function you provided when calling $(window).on(...) is different from the function you provided when you called $(window).off(...), that is the reason it didn't work (and it is the reason you have to save the reference to the actuall function you are providing when calling $(window).on(...).

Upvotes: 4

Related Questions