2

I'm aware that $destroy should be used to avoid memory leaks, but it's not clear what is precise and definitive list of cases when such leaks can occur.

When exactly should one call $destory on scope?

This question is not about does or not $destroy removes event listeners. It is question for list of cases when one should deliberately call of $destroy() method. Also this question is not about $on('$destroy').

setec
  • 15,506
  • 3
  • 36
  • 51
  • Possible duplicate of [AngularJS - Does $destroy remove event listeners?](http://stackoverflow.com/questions/26983696/angularjs-does-destroy-remove-event-listeners) – Estus Flask Jul 25 '16 at 12:31
  • @estus defintely not. This is completely different question. – setec Jul 25 '16 at 13:09
  • The first and the second part of the question aren't related. The first part concerns $destroy *event*, and the answer to the first part is the link above. *These* are the circumstances under which the leaks can occur. The second part concerns $destroy *method*, and the answer is 'virtually never'. It should be a unit that creates its own set of scopes after its initialization and destroys them before its destruction - maybe a modal manager or an alternative to ng-repeat or existing router. – Estus Flask Jul 25 '16 at 13:32

2 Answers2

1

Imho the most important case when you should free resources on $destroy is removing event listeners, which were set using addEventListener(). Another case is setTimeout / setInterval calls, which are not tracked by Angular as $timeout and $interval services and thus can lead to memory leaks.
As a matter of fact you should not call $destroy, but rather catch $destroy event by calling

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

and release all significant resources inside the passed function.

Ilya_S
  • 184
  • 2
  • 1
    Sorry, the question is exactly about deliberate call of $destroy() method. Not about $on('$destroy'). – setec Jul 25 '16 at 09:44
1

I am not too sure if this answers your question but maybe this will help you.

Scope data goes through a life cycle while the application is loaded in the browser.

The 5 Phases are

1) Creation- The root scope is created during the application bootstrap by the $injector. During template linking, directives(not all) create new child scopes.

2) Watcher Registration - During template linking directive registers watches on the scope. These watchers will be used to propagate model values to the DOM.

3) Model Mutation- For Mutations to be properly observed, you should make them only within the scope.$apply(). Angular API's do this implicitly , so no extra $apply call is needed when doing synchronous work in controllers , or async work with $http, $timeout or $interval services.

4) Mutation Observation- At the end of $apply(), Angular performs a $digest cycle on the $rootscope, which then propagates throughout all child scopes. During the $digest cycle, all $watched expressions or functions are checked for model mutation and if a mutation is detected, the $watch listener is called.

5) Scope Destruction- When child scopes are no longer needed , it is the responsibility of the child scope creator to destroy them via scope.$destroy()API. This is done in order to stop propagation of $digest calls into the child scope and allow for memory used by the child scope models to be reclaimed by the garbage collector.

I guess i somewhat tried answering your question towards the end. Hope it helps :)

ankurJos
  • 496
  • 4
  • 16
  • @ajacts as I got it, $destroy() should be called only in case when child scope has been created manually? Can you provide an example? – setec Jul 25 '16 at 13:12
  • @setec . Yes you are right, $destroy() should be called only when a child scope has been created manually. Also, in most cases the child scope is created automatically every time we use Directives. (e.g ng-controller, ng-app) and hence $destroy() function is called automatically. – ankurJos Jul 25 '16 at 13:58
  • @setec Also, as per your request for an example, currently i dont have one, (will definitely share one soon on this post). But for time being, you can refer to AngularJS documentation to create "isolate scopes". The "isolate scopes" that we create are the ones on which we would call the $destroy(). Hope i was helpful. – ankurJos Jul 25 '16 at 14:03