Angularjs 仅在一个控制器上调用$

Angularjs 仅在一个控制器上调用$,angularjs,angularjs-scope,Angularjs,Angularjs Scope,我有一个控制器,它有一个名为changeSafe的事件。我希望其他控制器在触发此事件时侦听 secure.controller('wrapperCtrl', function ($scope, $rootScope, storeFactory, safeFactory) { $scope.changeSafe = function (safeId) { $scope.loading = true; safeFactory.setSafe(safeI

我有一个
控制器
,它有一个名为
changeSafe
的事件。我希望其他控制器在触发此事件时侦听

secure.controller('wrapperCtrl', function ($scope, $rootScope, storeFactory, safeFactory) {    
    $scope.changeSafe = function (safeId) {
        $scope.loading = true;
        safeFactory.setSafe(safeId).then(function (safeData) {
            $scope.safe = safeData;
            $scope.loading = false;
            $rootScope.$broadcast('changeSafe', safeData);
        });
    }
});
当我添加页面下方的内容时,加载的第一个页面称为
dashboard
,并按照我的预期使用$scope.safe重新绘制

secure.controller('dashboardCtrl', function ($scope, $rootScope, storeFactory, safeFactory) {    
    $scope.$on('changeSafe', function (event, arg) {        
        bindSafe(arg.safeId);
    }); 
}); 
我的历史控制器上有几乎完全相同的东西

secure.controller('historyCtrl', function($scope, $rootScope, storeFactory, safeFactory) {
    $scope.$on('changeSafe', function (event, arg) {        
       bindHistory(arg.safeId);
    }); 
});
这是我在
config
一节中看到的

secure.config(['$routeProvider', function ($routeProvider) {
    $routeProvider
        .when('/history', {
            templateUrl: '/Angular/History/history.html',
            controller: 'historyCtrl'
        })
    .otherwise({
        templateUrl: '/Angular/Dashboard/dashboard.html',
        controller: 'dashboardCtrl'
    });
}]);
每当我单击
wrapperCtrl
中的按钮时,只有
$scope.$on
仪表板Ctrl
中触发。有人知道为什么
历史Ctrl
控制器没有触发
$scope.$on
吗?我也不清楚,当我不再在该视图上时,为什么会从
仪表板Ctrl
调用它


当我一步一步地浏览代码时,我实际上看到
$rootScope.$on('changeSafe')
在历史记录页面和仪表板页面上被多次调用。我不明白为什么它会将视图更改回仪表板,尽管我不确定是否完全了解您的问题,但我最好的猜测是您遇到了加载顺序问题,并且在订阅初始化之前正在广播事件


首先,为了省去很多麻烦,重要的是要充分了解:

  • 了解在$rootScope上订阅与在$ $scope.$on
  • 了解使用$broadcast和$emit进行发布的区别 $rootScope vs$scope
从评论中可以看出,您可能使用了$rootScope.$on,当您的控制器被销毁时,它不会被清除(与指令相同):

根据您的用例,在子作用域上注册侦听器将获取从$rootScope.$broadcast发布的事件(它将顶层向下通信到每个子作用域)。
您可能存在加载顺序问题?

可能是
historyCtrl
不是
wrapperCtrl
的后代,我在列出
wrapperCtrl
的标记中有一个典型的
ng视图。在我的
config
中,当打开
/history
时,我会告诉它控制器是
historyCtrl
,我也不清楚当我不再在该视图上时,为什么会从仪表板ctrl调用它:您需要注销在$rootScope上设置的事件侦听器(在$scope上的会自动注销)。否则,控制器将保持活动状态,当不需要时,这是一个内存泄漏。最好在进入单独视图时杀死它们吗?抱歉,我刚才看到您在$rootScope上广播,但在$scope上收听(之前没有注意到差异)。在这种情况下,您不需要取消注册它(尽管这也不会有什么坏处)。这个问题可能在你的bindSafe功能范围内?我找到了答案。在我的标签上有一个迷路的href=#uu,这就是路线改变的原因。我将回顾您发送的事件处理链接,但我需要更好地理解这一点,因为这样控制器就不会初始化
var changeSafeListnerUnbindFunction = $rootScope.$on('changeSafe', funciton() { //... });

$scope.$on('$destroy', changeSafeListnerUnbindFunction);