W3docs

How to Catch Directive Deletion

AngularJs lets us to use directives and make our code more professional.But sometimes we need to know when our directive has been removed.This snippet will show you how to know it.

The AngularJS framework is a popular and useful JavaScript library. If you are an AngularJS developer, you probably know about AngularJS Directives. Directives let you structure code in a modular way, similar to classes. You can create a directive and use multiple instances of that directive type.

Warning

Since AngularJS is now a deprecated framework, you can use modern JavaScript frameworks like Vuejs, React and Angular, instead.

As you know, ngRepeat, ng-click, ngShow, ngHide, etc., are all AngularJS directives. Let's talk a little about the ngRepeat directive.

Catching Directive Deletion

ngRepeat is a popular and very useful directive. You can use it wherever needed. You can create a directive and use its instances with ngRepeat. This way, you can render multiple objects.

Let's see an example:

Directive Example

<script>
    angular.module('MyModule', [])
        .directive('myDirective', function() { ... });
</script>
...
<my-directive ng-repeat="item in items"></my-directive> <!-- if you create a directive with restrict: 'E' -->

Now, imagine you want to know when a directive instance is removed (for example, when you remove an item from the array while using ngRepeat). You might wonder why this matters. For instance, you have points in a database that you want to draw on a map. You fetch the data, pass it to AngularJS, and AngularJS renders them.

You can create a directive called Marker to handle this. It looks like this:

Marker Example

<script>
    angular.module('Map', [])
        .directive('marker', function() { ... }) // this directive will draw the markers on the map
</script>

...

<marker ng-repeat="marker in dbMarkers"></marker> <!-- markers on the map -->

Let's say you want to remove a specific item (marker). You can remove it from the array, and ngRepeat will handle the DOM update. However, the marker will not be removed from the map, and you might be unsure if the item was actually removed or if the correct item was deleted. So, what should you do?

Here is the solution. Every directive instance triggers a $destroy event on its associated scope (isolated or inherited) before it is removed. You can listen to it like this:

Destroy in the directive

angular.module('MyModule')
    .directive('marker', function() {
        return {
            // ...
            link: function(scope, el) {
                scope.$on('$destroy', function() {
                    // do whatever you want
                    // for example: marker.setMap(null) to remove the marker from the map
                });
                // Note: The listener automatically unregisters itself when the scope is destroyed.
                // Alternatively, you can listen on the element itself:
                // el.on('$destroy', function() { ... });
            }
        };
    });