我正在使用Angular Route来构建SPA,其路由由公共父控制器封装。在父控制器内部,有一个按钮,它将发出一个假设被所有子/路由控制器捕获的事件,每个控制器决定如何处理它。
我希望此事件由父控制器发出一次,并由每个子/路由控制器接收一次。我在这里有一个Plunker http://plnkr.co/edit/9twoe6WO3eLQzVDatrC0?p=preview,表示尝试失败。
该代码段的问题在于,每次路由导航时,同一个子/路由控制器都会再次接收该事件。
PS:来自Plunker的代码
HTML
<body ng-controller="MainCtrl">
<ng-view></ng-view>
<button ng-click="navigate()">Propagate</button>
<script type="text/ng-template" id="viewIndexCtrl.html">
<p>this is index page</p>
</script>
<script type="text/ng-template" id="viewPackageCtrl.html">
<p>this is package page</p>
</script>
</body>
JS
var app = angular.module('plunker', ['ngRoute']);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.when('/index', {
controller: 'viewIndexCtrl',
templateUrl: 'viewIndexCtrl.html'
}).when('/package', {
controller: 'viewPackageCtrl',
templateUrl: 'viewPackageCtrl.html'
}).otherwise({
redirectTo: '/index'
});
}
]);
app.controller('MainCtrl', function($scope, $location, $rootScope) {
$scope.navigate = function() {
var route = location.href.indexOf('index') > -1 ? 'package' : 'index';
$location.path('/' + route);
$rootScope.$emit('navigate');
};
});
app.controller('viewIndexCtrl', function($scope, $rootScope) {
$rootScope.$on('navigate', function(e) {
e.preventDefault();
e.stopPropagation();
console.log('event reached index');
});
});
app.controller('viewPackageCtrl', function($scope, $rootScope) {
$rootScope.$on('navigate', function(e) {
e.preventDefault();
e.stopPropagation();
console.log('event reached package');
});
});
答案 0 :(得分:0)
$broadcast
而不是$emit
。$rootScope
上,每当一个控制器被销毁时,它的范围也会被破坏,因此所有它的范围监听器都会被自动删除,但当你把监听器放在{{1}上时你需要手动删除它们。您的代码中发生的事情是,您在每次路由更改时都会将一个侦听器附加到$rootScope
,而不会删除以前的侦听器。如果您使用控制器的本地$rootscope
,则无需执行任何操作。这可能就是您所需要的(plunker):
$scope