为什么模板内的控制器在监听 $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);
})
这看起来像是一个错误,但我的问题是为什么会这样?如果模板中定义的控制器正在监听 $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);
})