如何在ui-router中获知状态变更取消?

Fro*_*yon 7 angularjs angular-ui angular-ui-router

所以我在我的应用程序中使用UI-router,我使用$stateChangeStart监听器来显示加载器,$stateChangeSuccess然后隐藏加载器.这样我在状态转换之间有一个加载器.

$rootScope.$on('$stateChangeStart',
                function (event, toState, toParams, fromState, fromParams) {
///show loader
});

$rootScope.$on('$stateChangeSuccess',
                function (event, toState, toParams, fromState, fromParams) {
//hide loader
});
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 我在A州
  2. 我点击按钮进入状态B,$stateChangeStart呼叫B,我的装载机显示.
  3. 我立即点击另一个按钮进入状态A(B有一些要解决的东西,所以在B的UI实际开始加载之前有时间)
  4. B没有被加载,并且$stateChangeSuccess没有被调用,我的加载器从未被隐藏(因为我们已经在A中,它没有重新加载)

那么有没有办法可以监听状态更改取消并隐藏我的加载程序?

更新:我创建了一个Plunk.在插入中,我已经在B的决心中给出了10秒的超时时间.因此,在它结算之前,单击A.监视控制台以获取状态更改侦听器事件.

2015年7月25日更新,使用最新的AngularUI路由器:创建新的Plunk.

Kir*_*tin 3

到目前为止,我发现的唯一可持续的解决方案是避免使用ui-sref. $state.go它掩盖了本例中关键的返回值。

诀窍是处理transition返回的承诺$state.go

$scope.safeGo = function(stateName){
  var transition = $state.go(stateName);
  transition.then(function(currentState){
    console.log('Transition finished successfully. State is ' + currentState.name);
  })
  .catch(function(err){
    //revert your loader animation here
    console.log('Transition failed. State is ' + $state.current.name, err);
  })
}
Run Code Online (Sandbox Code Playgroud)

可以通过属性访问同一对象$state.transition,但是在转换之间null以及广播该属性的任何事件中$state也可以访问该属性null。因此,唯一可靠的选择是获取 的返回值$state.go

当在解决A之前选择状态时,承诺将拒绝并给出理由。但是您仍然需要等待完成。如果您想避免这种情况,您将必须自己跟踪您的状态,因为转换到将立即解决(因为当前状态在尝试解决时仍然是)。BtransitionBError: transition supersededB.resolveAAB

更新了笨蛋