2

I have an AngularJS directive and I need to perform certain actions if the directive's element is removed from the DOM (either from inside an AngularJS call or by any other method, like jQuery).

Is that possible?

alexandernst
  • 14,352
  • 22
  • 97
  • 197

2 Answers2

8

In the directive, when an element is removed from DOM, $destroy event is emitted. Inside your directive's link function, you can do this:-

element.on('$destroy', function() {
   // do stuff
});

For more information and complete example, see documentation here

EDIT: See this plunker to see $destroy in action. Here, I am removing the element after 2 seconds, and logging destroyed in console.

Abhishek Jain
  • 2,957
  • 23
  • 35
  • Please check http://stackoverflow.com/questions/30778150/detect-if-directive-was-removed-from-dom#comment49607117_30778318 – alexandernst Jun 11 '15 at 10:43
  • Can you share a plunker, so that we can see what exactly are you doing. – Abhishek Jain Jun 11 '15 at 10:58
  • Updated my answer with a working plunker. I am using angular.element (which is wrapper around jQuery/jqLite) to remove the element, to keep it within the angular world. – Abhishek Jain Jun 11 '15 at 11:10
  • Ok, I'm getting the destroy event (I switched to angular.element). Now there is another problem: the directive is complaining about a repeated item in a `ng-repeat` after recreating the directive. I tracked down the problem to the data that I'm passing to the directive getting duplicated (or even triplicated). Not really sure what is going on there. Do I need to know any tricks when dealing with destroying/recreating a directive? Why could the data be getting duplicated? – alexandernst Jun 11 '15 at 11:19
  • Please share a plunker so that we can see what is going on. Without that, we would just be guessing. :-) – Abhishek Jain Jun 11 '15 at 11:20
  • Ok, let me try to make a plunkr with that. Thing is, the entire thing is quite compex and I'd need some time. – alexandernst Jun 11 '15 at 11:21
  • I made it! I was forced to refactor my code and I found where the bug was coming from :) – alexandernst Jun 11 '15 at 15:03
1

When your directive is removed from the DOM, an $destroy event is fired. See here https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$destroy

In this question (Provide an example of scope's $destroy event?) I found the following example:

ctrl.directive('handleDestroy', function() {
    return function(scope, tElement, attributes) {        
        scope.$on('$destroy', function() {
            alert("In destroy of:" + scope.todo.text);
        });
    };
});
Community
  • 1
  • 1
23tux
  • 14,104
  • 15
  • 88
  • 187
  • I'm removing some elements (including my directive with `$('selector').html("")`, but my directive isn't firing that callback. Maybe `.html("")` is not actually removing from the DOM? Or maybe I need to apply the change somehow? – alexandernst Jun 11 '15 at 10:42
  • You could try two things: First, don't remove the elements with plain jQuery, try the `ng-if` directive. If this doesn't work, check out some other questions: http://stackoverflow.com/questions/26983696/angularjs-does-destroy-remove-event-listeners http://stackoverflow.com/questions/13481992/does-removing-a-dom-element-remove-the-associated-scope http://stackoverflow.com/questions/17855203/do-we-need-to-unbind-event-listeners-in-directives-when-angular-starts-to-destro – 23tux Jun 11 '15 at 11:26