停转的UI路由器导航,直至承诺解决 [英] stop angular-ui-router navigation until promise is resolved

查看:227
本文介绍了停转的UI路由器导航,直至承诺解决的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要prevent一些闪烁时,导轨设计超时发生这种情况,但角度并不知道,直到从资源的下一个授权错误。

什么情况是,模板呈现出来,对资源的一些Ajax调用发生,然后我们被重定向到轨设计登录。我宁愿做一个ping到轨道上的每一个状态变化,如果轨道会话已过期,那么我会立即重新定向之前,模板被渲染。

UI的路由器解决,可以把每路线,但似乎干不可言。

我这是什么。但这个承诺没有得到解决之前,国家已经转变。

  $ rootScope。在$('$ stateChangeStart',函数(事件,toState,toParams,fromState,fromParams){
        //检查用户登录
        $ http.get('/ API /平')。成功(功能(数据){
          如果(data.signed_in){
            $ scope.signedIn =真;
          }其他{
            window.location.href ='/导轨/色器件/ login_path
          }
        })    });

我怎么能中断状态转换,新的模板被渲染之前的基础上,承诺的结果?


解决方案

我相信你正在寻找事件。preventDefault()


  

注意:使用事件preventDefault(),以prevent情况发生转变


  $范围。在$('$ stateChangeStart',
功能(事件,toState,toParams,fromState,fromParams){
        。事件preventDefault();
        // transitionTo()承诺将与拒绝
        //一个过渡prevented错误
})

虽然我可能会使用决心状态配置为@charlietfl建议

修改

所以我有机会使用preventDefault()的状态改变事件,并在这里是我做过什么:

  .RUN(函数($ rootScope,$状态,$超时){$ rootScope。在$('$ stateChangeStart',
    功能(事件,toState,toParams,fromState,fromParams){        //检查用户是否被设置
        如果($ rootScope.u_id和放大器;!&安培;!toState.name =='登入'){
            。事件preventDefault();            //如果没有延迟,您将获得竞争条件为$申请正在进行中
            $超时(函数(){
                event.currentScope。$应用(函数(){
                    $ state.go(登入)
                });
            },300)
        }其他{
            //做别的未便
        }
    }
)}

修改

较新的文档包括示例一个人如何应用户同步() preventDefault 被调用后继续,但的exaple只要使用 $ locationChangeSuccess 事件,这对我和评论者不工作,而是使用 $ stateChangeStart 在下面的例子中,从文档采取更新事件:

  angular.module('应用',['ui.router'])
    .RUN(函数($ rootScope,$ urlRouter){
        $ rootScope。在('$ stateChangeStart',函数(EVT){$
            //从开始甚至停止状态变化
            。EVT preventDefault();
            //执行自定义逻辑
            VAR meetsRequirement = ...
            //使用更新和状态转换,如果继续允许逻辑
            如果(meetsRequirement)$ urlRouter.sync();
        });
    });

I want to prevent some flickering that happens when rails devise timeout occurs, but angular doesn't know until the next authorization error from a resource.

What happens is that the template is rendered, some ajax calls for resources happen and then we are redirected to rails devise to login. I would rather do a ping to rails on every state change and if rails session has expired then I will immediately redirect BEFORE the template is rendered.

ui-router has resolve that can be put on every route but that doesn't seem DRY at all.

What I have is this. But the promise is not resolved until the state is already transitioned.

$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
        //check that user is logged in
        $http.get('/api/ping').success(function(data){
          if (data.signed_in) {
            $scope.signedIn = true;
          } else {
            window.location.href = '/rails/devise/login_path'
          }
        })

    });

How can I interrupt the state transition, before the new template is rendered, based on the result of a promise?

解决方案

I believe you are looking for event.preventDefault()

Note: Use event.preventDefault() to prevent the transition from happening.

$scope.$on('$stateChangeStart', 
function(event, toState, toParams, fromState, fromParams){ 
        event.preventDefault(); 
        // transitionTo() promise will be rejected with 
        // a 'transition prevented' error
})

Although I would probably use resolve in state config as @charlietfl suggested

EDIT:

so I had a chance to use preventDefault() in state change event, and here is what I did:

.run(function($rootScope,$state,$timeout) {

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

        // check if user is set
        if(!$rootScope.u_id && toState.name !== 'signin'){  
            event.preventDefault();

            // if not delayed you will get race conditions as $apply is in progress
            $timeout(function(){
                event.currentScope.$apply(function() {
                    $state.go("signin")
                });
            },300)
        } else {
            // do smth else
        }
    }
)

}

EDIT

Newer documentation includes an example of how one should user sync() to continue after preventDefault was invoked, but exaple provided there uses $locationChangeSuccess event which for me and commenters does not work, instead use $stateChangeStart as in the example below, taken from docs with an updated event:

angular.module('app', ['ui.router'])
    .run(function($rootScope, $urlRouter) {
        $rootScope.$on('$stateChangeStart', function(evt) {
            // Halt state change from even starting
            evt.preventDefault();
            // Perform custom logic
            var meetsRequirement = ...
            // Continue with the update and state transition if logic allows
            if (meetsRequirement) $urlRouter.sync();
        });
    });

这篇关于停转的UI路由器导航,直至承诺解决的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆