Angularjs 为什么$stateChangeStart会触发多次?

Angularjs 为什么$stateChangeStart会触发多次?,angularjs,angular-ui-router,Angularjs,Angular Ui Router,我正在尝试将$stateChangeStart与控制器中的ui路由器一起使用。似乎每次启动回调时,回调的启动次数都是上次的+1倍 $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ console.log('$stateChangeStart'); }); 例如,在第一次更改时,启动console.log将触发一次。第二次控制台。日志将触发两次,以此

我正在尝试将
$stateChangeStart
与控制器中的ui路由器一起使用。似乎每次启动回调时,回调的启动次数都是上次的+1倍

$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
    console.log('$stateChangeStart');
});
例如,在第一次更改时,启动
console.log
将触发一次。第二次
控制台。日志将触发两次,以此类推

我知道使用
event.preventDefault()
将停止此行为,但它也将停止所有行为,这对我来说不是一个现实的解决方案

我确实有一个解决方案,尽管我觉得可能有一个更聪明的方法来处理这个问题:

var stateChangeStarted = false;
$rootScope.$on('$stateChangeStart', function(event){
    if(!stateChangeStarted) {
        stateChangeStarted = true;
        console.log('$stateChangeStart');
    }
});

有人知道为什么会发生这种情况吗?我还能做些什么来防止这种情况发生?

每当您进入控制器关联的状态时,您的控制器都会被ui路由器实例化。因此,每次进入
$rootScope.$on
调用时,都会向
$stateChangeStart
事件添加一个新的侦听器

如果每个控制器实例只需要处理一次事件,则可以保存
$rootScope.$on
返回的注销函数,并从侦听器回调中执行该函数

var deregisterStateChangeStart = $rootScope.$on('$stateChangeStart', function (event) {
    // Do something here.

    deregisterStateChangeStart();
});

清除控制器开头的stateChangeStart侦听器

$rootScope.$$listeners.$stateChangeStart = [];

如果您在同一个控制器中从一个状态url切换到另一个状态url,则此stateChangeStart仅触发一次。