16

Inside one of my directives, I use angular.element($window).bind('scroll'). When the directive is destroyed, I then want to unbind it. Normally, I would just do:

$scope.$on('$destroy', function()
{
    angular.element($window).unbind('scroll');
});

But what if another directive also has binded to the scroll event of the $window, and that event still needs to exist. If I use the unbind above, the other directive's binding is also eliminated.

What are my options?

4 Answers 4

37

Pass the same function reference to unbind/off as you pass to bind/on to unbind just that particular handler:

var fn = function () {};

angular.element($window).on('scroll', fn);

angular.element($window).off('scroll', fn);

For example:

var onScrollAction = function () {
  // Do something 
};

angular.element($window).on('scroll', onScrollAction);

scope.$on('$destroy', function () {

  angular.element($window).off('scroll', onScrollAction);
});

Note that in jQuery the functions bind and unbind are deprecated. You can however still use them both with jQuery and jqLite as they just call on and off behind the scenes.

Sign up to request clarification or add additional context in comments.

5 Comments

Angularjs's jqLite doesn't support namespace. On that case how to avoid the same problem?
scroll does not count as a namespace. A namespace would be scroll.myPlugin or .myPlugin. So the answer still works and will unbind the passed handler from the specified event.
When you downvote, please be kind and leave a reason.
@tasseKatt, This isn't the first time this has happened but I discovered this answer in my stack overflow activity having no recollection of the question let alone down voting it. Must be my cat. Anyways this answer looks good to me so I've changed it to an up vote.
@ShannonPoole Classic cat :) Thanks!
1

JQuery's on() supports namespacing events so they can be removed independent of each other.
(https://api.jquery.com/on/)

Angular's jqLite however, does not.
(https://docs.angularjs.org/api/ng/function/angular.element)

But if you include JQuery before Angular then JQuery will replace jqLite and you should be able to use namespaces. That's possibly not what you wanted to hear, but I'm not aware of any other way.

Comments

0

Just for more clearity on how it will goes in directive Within link function just use this make sure attach it to write element as in example it is attached to document

                //attach event to document which is big thing
                //make sure we remove it once we done with this
                $document.on('keydown', handler);

                //We need to remove this event as it should be only applicable when user is withing 
                //the scope of directive parent
                scope.$on("$destroy", function () {
                    $document.off('keydown', handler);
                });
                //function gets executed when we hit the key specified from form
                function handler (event) {
                }

Comments

0

bind:

$window.onscroll = function() {
//your code
};

unbind:

$scope.$on('$destroy', function () {
     $window.onscroll = undefined;
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.