【问题标题】:Pause transition and restart after async call异步调用后暂停转换并重新启动
【发布时间】:2014-02-08 07:57:00
【问题描述】:

我想检查每次我转换到的状态或它的父级是否有一些 isLogged 数据属性时记录用户。我的代码是:

        service.watchHasAccess = function(){
        $rootScope.$on('$stateChangeStart', function(event,toState,toStateParams){
            if(typeof toState.data !=='undefined' && typeof toState.data.loggedIn !== 'undefined' && toState.data.loggedIn == true){
                api.getWithPromise('user/isLoggedIn').then(function(response){
                    if(response.status !=='OK'){
                        event.preventDefault();
                        FlashMessage.showError('Zaloguj się aby przejść tutaj.');
                        $state.go('MainPage');                            
                    }
                });
            }
        });

问题是当转换到受限状态时它会加载,但它几乎立即重定向到 MainPage 状态。这就像闪光灯。这是因为我使用异步请求,所以我假设状态只是转换,无论请求的结果是什么,但随后响应来了,我被正确地转换了。我想要实现的是等到承诺得到解决然后检查并最终将用户重定向到'MainPage'。这可能吗?

【问题讨论】:

    标签: javascript angularjs angular-ui-router


    【解决方案1】:

    您需要为您的 asyc 使用 Promise,并根据返回的内容解决或拒绝该 Promise。我建议 URL 切换将在 $stateChangeError 事件侦听器中进行,该事件侦听器会因拒绝承诺而被触发。你可以将reject([data])中你想去的位置传递给监听器。

    http://fiddle.jshell.net/L9jxf/2/

    一些承诺会在超时后拒绝(模拟服务器调用)

            protected: ['$timeout', '$q', function ($timeout, $q) {
                var deferred = $q.defer();
                $timeout(function () {
                    deferred.reject({type:'redirect',location:'401'});
                }, 1000);
                return deferred.promise;
            }]
    

    这会处理拒绝

    app.run(function ($rootScope, $state) {
        $rootScope.$on('$stateChangeError', function (e, to, toParams, from, fromParams, error) {
            if (error.type === 'redirect') {
                $state.transitionTo(error.location);
            }
        });
    });
    

    【讨论】:

    • 我设法做到了,但我还有一个问题。我将此解决方案置于“用户”状态,因此如果我转到“user.stuff”,将再次检查该解决方案。问题是,当我进入“user.anything”状态时,这个解析会被处理一次,然后当我进入“user.anything2”时,它不会再次被解析。我有点理解为什么会发生这种情况,但问题是是否有比将 $state.reload() 放在“用户”状态内部使用的每个控制器之上更好的解决方案。希望你能理解我的问题:)
    • 我想我明白了。您有多个嵌套在 user 状态中的状态。您希望 user 状态在每次访问其中的任何状态时解析。我不认为这是可能的。在兄弟姐妹中导航时,父状态永远不会重新加载,因此永远不会重新解析。除了$state.reload(),您还可以将解决方案放在需要它的每个州。
    • 我认为这样做有点矫枉过正,我使用了 [code]$state.reload()[/code] 因为我知道登录时总是需要使用这个控制器。无论如何谢谢你的回答:)
    猜你喜欢
    • 2014-02-15
    • 1970-01-01
    • 2019-05-11
    • 2021-06-15
    • 2016-03-22
    • 2020-09-24
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多