2014-11-16 44 views
1

我正在使用Angular Route來構建SPA,其中包含由公共父控制器封裝的路由。在父控制器內部,有一個按鈕會發出一個假設被所有子/路由控制器捕獲的事件,每個控制器都決定如何處理它。無法停止AngularJS中路由控制器之間的事件傳播

我希望這個事件由父控制器發出一次,並由每個子/路由控制器接收一次。我在這裏有一個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
  • 你需要的是用$broadcast而非$emit
  • 你把聽衆放在$rootScope上,無論何時一個控制器被銷燬,它的範圍也會被銷燬,因此所有的範圍監聽器都會被自動刪除,但是當你把監聽器放在$rootScope上時,你需要手動刪除它們。代碼中會發生什麼情況:您將每個路由更改附加一個偵聽器到$rootscope而不刪除以前的偵聽器。如果您使用控制器的本地$scope,則無需執行任何操作。

這可能是你所需要的(plunker):

app.controller('MainCtrl', function($scope, $location, $rootScope, $timeout) { 
    $scope.navigate = function() { 
    var route = location.href.indexOf('index') > -1 ? 'package' : 'index'; 
    $location.path('/' + route); 
    // $location.path happens only after the digest cycle so we must wait for it.. 
    $timeout(function() { 
     $rootScope.$broadcast('navigate'); 
    }); 
    }; 
}); 

app.controller('viewIndexCtrl', function($scope, $rootScope) { 
    $scope.$on('navigate', function(e) { 
    console.log('event reached index'); 
    }); 
}); 
app.controller('viewPackageCtrl', function($scope, $rootScope) { 
    $scope.$on('navigate', function(e) { 
    console.log('event reached package'); 
    }); 
});