如果它听取$ rootScope,为什么模板内的控制器不会被破坏

时间:2015-02-01 13:05:48

标签: angularjs angular-ui-router

它看起来像一个bug,但我的问题是为什么会发生这种情况?在$ stateProvider中查看下面的代码,如果模板中定义的控制器正在监听$ rooScope上的事件,即使状态发生变化,每次相同状态都会创建新控制器,此控制器也不会销毁

<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之间的多次点击然后广播

enter image description here

1 个答案:

答案 0 :(得分:2)

这不是一个错误。

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

因此,控制器需要通过在其本地$destroy上侦听$scope事件并在调用$rootScope.$on的初始调用返回的注销功能后自行清理。 :

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