如何获知 ui-router 中的状态更改取消?
How to be informed of state change cancellations in 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
});
问题:
- 我处于状态 A
- 我点击一个按钮进入状态B,
$stateChangeStart
为B调用,显示我的加载程序。
- 我立即点击另一个按钮进入状态 A(B 有一些东西需要解决,所以在 B 的 UI 实际开始加载之前还有时间)
- B 未加载,
$stateChangeSuccess
未被调用,我的加载器从未被隐藏(因为我们已经在 A 中,所以不会重新加载)
那么有什么方法可以监听状态更改取消并隐藏我的加载器吗?
更新:
我创建了一个 Plunk。在 plunk 中,我在 B 的 resolve 中设置了 10 秒的超时。所以在它解决之前,点击 A。监视状态更改侦听器事件的控制台。
2015 年 7 月 25 日更新,使用最新的 AngularUI 路由器:
创建了新 Plunk。
到目前为止,我发现的唯一可持续解决方案是避免使用 ui-sref
。它屏蔽了 $state.go
的 return 值,这在本例中是关键。
诀窍是处理由 $state.go
编辑的 transition
承诺 return
$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);
})
}
可以通过 $state.transition
属性 访问同一对象,但是在转换之间 属性 是 null
并且在 $state
广播的任何事件中它也是 null
。因此,唯一可靠的选择是获取 $state.go
.
的 return 值
如果在 B
解决之前选择了状态 A
,B
的 transition
承诺将被拒绝,原因是 Error: transition superseded
。但是,您仍然需要等到 B.resolve
完成。如果你想避免这种情况,你将不得不自己跟踪你的状态,因为到 A
的转换将立即得到解决(因为当前状态仍然是 A
而 B
正在尝试解决)。
已更新plunker
所以我在我的应用程序中使用 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
});
问题:
- 我处于状态 A
- 我点击一个按钮进入状态B,
$stateChangeStart
为B调用,显示我的加载程序。 - 我立即点击另一个按钮进入状态 A(B 有一些东西需要解决,所以在 B 的 UI 实际开始加载之前还有时间)
- B 未加载,
$stateChangeSuccess
未被调用,我的加载器从未被隐藏(因为我们已经在 A 中,所以不会重新加载)
那么有什么方法可以监听状态更改取消并隐藏我的加载器吗?
更新: 我创建了一个 Plunk。在 plunk 中,我在 B 的 resolve 中设置了 10 秒的超时。所以在它解决之前,点击 A。监视状态更改侦听器事件的控制台。
2015 年 7 月 25 日更新,使用最新的 AngularUI 路由器: 创建了新 Plunk。
到目前为止,我发现的唯一可持续解决方案是避免使用 ui-sref
。它屏蔽了 $state.go
的 return 值,这在本例中是关键。
诀窍是处理由 $state.go
transition
承诺 return
$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);
})
}
可以通过 $state.transition
属性 访问同一对象,但是在转换之间 属性 是 null
并且在 $state
广播的任何事件中它也是 null
。因此,唯一可靠的选择是获取 $state.go
.
如果在 B
解决之前选择了状态 A
,B
的 transition
承诺将被拒绝,原因是 Error: transition superseded
。但是,您仍然需要等到 B.resolve
完成。如果你想避免这种情况,你将不得不自己跟踪你的状态,因为到 A
的转换将立即得到解决(因为当前状态仍然是 A
而 B
正在尝试解决)。
已更新plunker