简体   繁体   中英

Angular 1.5 Components difference between $onDestroy & $scope.$destroy()

I'm trying to understand the difference between the controller's $onDestroy method and $scope.$destroy() .

Definition says that $onDestroy is called when the containing scope of the component needs to be destroyed. But isn't it the same case with $scope.$destroy()?

As per the plunker I've created at https://plnkr.co/edit/9RlS8OLxAoyK80WPMJaN?p=preview ,

<div ng-controller="ParentController">
    <button ng-click="func()">Parent</button>
    <br><br>
    <div ng-controller="ChildController">
      <button ng-click="childFunc()"> Child </button>
      <br><br>
      <comp> </comp>
    </div>
</div>

I've noticed two situations.

  1. When I call $destroy() from the Parent or Child controller, both $onDestroy and $scope.$on('$destroy') events are triggered in the Component. This makes sense as the containing scope of the component is destroyed when the Parent scope is destroyed. However, I'm still able to click the 'Component FUNC' button and call the function associated with it. Why does this happen?

  2. When I call $destroy() from the Component itself, then only the $scope.$on('destroy') event is triggered leaving behing the $onDestroy untriggered. Also, I'm not able to access the 'Component FUNC' button as I was able to do in Case #1.

Can someone please explain me the difference in the two cases?

This is not a real life use-case but something that I wanted to understand.

Thank you.

Take a look at the following links:

https://github.com/angular/angular.js/issues/15073
https://github.com/angular/angular.js/issues/14376

To summarize, the explanation they give is the following:

There is a misconception that controller.$onDestroy() is equivalent to $scope.$on('$destroy'), where $scope is the scope passed to the controller. This is not always the case.

More specifically, controller.$onDestroy() is called when the scope where the controller "lives in" gets destroyed. When you have an isolate scope directive, the scope passed (as $scope) to the controller is not the scope that the controller lives in, it is a child-scope that is created for the directive's template. Thus, calling $scope.$destroy() will NOT destroy the scope that the controller lives in (and NOT call controller.$onDestroy()).

The only case, where controller.$onDestroy() is equivalent to $scope.$on('$destroy') is when having a directive with scope: false. This means that no new scope is created, so the scope passed (as $scope) to the controller is the same scope that the controller lives in.

This explains the second situation, but I still don't get why you can call the function associated with the 'Component FUNC' button even after you have called $destroy().

I hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM