为什么$ stateChangeStart会多次触发?

时间:2014-11-22 00:16:21

标签: angularjs angular-ui-router

我正在尝试在控制器中使用带有ui路由器的$stateChangeStart。看起来好像每次被解雇,回调比上一次激发+1倍。

$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
    console.log('$stateChangeStart');
});

例如,首次更改开始console.log将被触发一次。第二次console.log将被解雇两次,等等。

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

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

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

有没有人知道为什么会这样,我还能做些什么来防止这种情况?

2 个答案:

答案 0 :(得分:18)

每次进入与之关联的状态时,ui-router都会对您的控制器进行实例化。因此,每次进入该状态时,您的$rootScope.$on来电都会为$stateChangeStart事件添加新的听众。

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

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

    deregisterStateChangeStart();
});

答案 1 :(得分:6)

清除控制器开头的stateChangeStart监听器。

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