它看起来像一个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之间的多次点击然后广播
答案 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);
})