我有一个 AngularJS 应用程序,它使用 ui-router 和ui-router-extras,其中状态之间的一些转换被拦截并重定向到另一个状态。
所以基本上,当一个$stateChangeStart
事件被触发时,应用程序会检查该转换是否被允许或需要被阻止,然后将用户重定向到其他地方(例如:登录对话框、流程中缺少的步骤等)。也可以取消转换。
拦截是这样工作的:
$rootScope.$on("$stateChangeStart", function(e,to,toParams,from,fromParams){
if( <mustBeIntercepted> || <mustBeCancelled> ){
// this prevents the actual state change from happening
e.preventDefault();
if( <redirectionRequired> ){
$state.go( <stateName>, <stateParams>);
}
}
});
到目前为止,这很好用。问题是,当取消状态更改时,$previousState
不知道取消,并将当前的注册为先前的,就像您不取消转换时一样。所以基本上$previousState
不知道过渡取消。这导致当尝试以编程方式返回到先前的状态时,它不会移动,因为$state
== $previousState
。
我在这里创建了一个现场演示:http: //plnkr.co/edit/dXjj2iSwDU1DtPMuqW1W ?p=preview
基本上,您单击Step1,然后单击Confirm,应用程序将取消转换并提示您是否要确认。如果您确认,那么它将过渡到最初想要的状态。请注意,在真正的应用程序中,这不是通过confirm
自定义覆盖完成的,而是使用无法以相同方式阻止答案的自定义覆盖confirm
。
您会注意到,在顶部栏中,有两个标签显示 和 的$state
内容$previousState
。如果您取消confirm
提示,您将看到$previousState
对“Step1”的更改,尽管没有发生转换。
我怎样才能避免这种情况?