为什么模板内的控制器在监听 $rootScope 时不会被破坏

Why controller inside template is not destroy if it listen to $rootScope

这看起来像是一个错误,但我的问题是为什么会这样?如果模板中定义的控制器正在监听 $rooScope 上的事件,请查看 $stateProvider 中的以下代码,即使状态发生更改,该控制器也不会销毁,并且每次相同状态时都会创建新控制器

<base href="/">

<div ng-app="myApp" ng-controller="MainCtrl">
  <a href="#/page1"> page1 </a> 
  <a href="#/page2"> page2 </a>
  <a href ng-click="clicked()"> broadcast</a>

  <div ui-view> </div>
</div>

<script>
angular.module('myApp', ['ui.router'])
.config(function ($stateProvider) {

$stateProvider
.state('search', {
    url: '/page1',
    templateUrl: '/page1.html',
    controller: 'testCtrl'
})

.state('/', {
  url: '/page2',
  templateUrl: '/page2.html'
})
})

 .controller('MainCtrl', function($rootScope, $scope){
   $scope.clicked = function(){
      $rootScope.$broadcast('hi')
   }
 })

.controller('SecondCtrl', function($rootScope, $scope){
  $rootScope.$on('hi', function(){
   console.log('SecondCtrl: hi broadcast received' + new Date())
  })
})

我知道这个问题可以通过听 $scope 而不是 $rootScope 来解决,但我的问题是幕后原因是什么?因为在其他情况下可能会发生监听 rootScope 很重要的情况。

page1 和 page2 之间的多次点击然后广播的简单输出

这不是错误。

当您调用 $rootScope.$on 时,它会在 $rootScope 上注册一个侦听器。它无法知道您从哪个控制器调用 $on,因此它不知道根据您的应用程序的设计,当控制器被移除时,侦听器也应该被移除。

因此,控制器将需要通过在其本地 $scope 上侦听 $destroy 事件并调用初始调用返回的注销函数来手动清理 [=11] =]:

.controller('SecondCtrl', function($rootScope, $scope){
  var deregister = $rootScope.$on('hi', function(){
    console.log('SecondCtrl: hi broadcast received' + new Date())
  });
  $scope.$on('$destroy', deregister);
})