3

Now I'm getting rid of $scope dependency from my angular controller to ensuring that I could easily migrate my code to Angular2. My current angular version is 1.4.X. While doing the same thing there is place while I placed $destroy listener over my controller scope like $scope.$on('$destory', function() ....).

I can see $on method only available on $scope of controller, but how can I achieve it without using $scope dependency.

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299

2 Answers2

3

If you are using angular 1.5+ they added lifecycle hooks that you can opt into on your controller. No $scope needed. Just add a function called $onDestroy() to your controller and it will be called when your controller is being clean up:

$onDestroy() - Called on a controller when its containing scope is destroyed. Use this hook for releasing external resources, watches and event handlers.

Example from http://blog.thoughtram.io/angularjs/2016/03/29/exploring-angular-1.5-lifecycle-hooks.html:

function MyCmpController($element) {

  var clickHandler = function () {
    // do something
  };

  this.$onInit = function () {
    $element.on('click', clickHandler);
  };

  this.$onDestroy = function () {
    $element.off('click', clickHandler);
  };
}
pgreen2
  • 3,601
  • 3
  • 32
  • 59
  • Thanks for sharing this too. Mine answer just solves the problem till 1.4.X version, but your solution looks promising to me as it will work for 1.5+, basically I had my project on 1.4.X version and was struggling to make it working from couple of hours and `$element.$on('$destroy',...)` working.. So I added it, Thanks :-) – Pankaj Parkar Jul 27 '16 at 06:19
2

After some research I found that the $destroy event is emitted while removing DOM & on that same DOM scope it broadcasts $destroy event, but at the same time same that event has been propagated on DOM which is going to be removed.

You know there is one dependency $element, if you inject that in controller will give you the DOM where you have ng-controller directive place. So inject $element inside your controller & then place listener over it like below

$element.on('$destroy', function(){
   //write clean up code here
});

Mine solution will work till 1.4.X version. For 1.5.3+ version you could use Angular lifecycle hook which is $onDestroy like shown by @pgreen2 in above answer. Thanks :)

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299