为什么$ stateChangeStart会多次触发?

muu*_*ess 9 angularjs angular-ui-router

我试图$stateChangeStart在控制器中使用ui路由器.似乎每次被解雇时,回调比上次发射+1次.

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

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

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

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

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

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

小智 18

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

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

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

    deregisterStateChangeStart();
});
Run Code Online (Sandbox Code Playgroud)


duy*_*yen 7

在控制器的开头清除stateChangeStart的监听器.

$rootScope.$$listeners.$stateChangeStart = [];
Run Code Online (Sandbox Code Playgroud)