我想防止一些闪烁发生时,发生rails发生超时,但角不知道,直到下一个授权错误从资源。
发生什么是模板被渲染,一些ajax调用资源发生,然后我们被重定向到rails devise登录。我宁愿做一个ping到每个状态更改的rails,如果rails会话已过期,我将立即重定向之前的模板呈现。
ui路由器有解决方案,可以放在每个路由,但似乎不是干的。
我有这个。但是,在国家已经过渡之前,承诺才能解决。
$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' } }) });
如何在呈现新模板之前基于promise的结果中断状态转换?
我知道这是非常晚的游戏,但我想把我的意见,在那里讨论我相信是一个很好的方式来“暂停”国家的变化。根据angular-ui-router的文档,状态的promise的“resolve”对象的任何成员必须在状态完成加载之前解决。所以我的功能(虽然还没有清理和完善)解决方案,是在“$ stateChangeStart”的“toState”的resolve对象中添加一个promise:
例如:
$rootScope.$on('$stateChangeStart',function (event,toParams) { toState.resolve.promise = [ '$q',function($q) { var defer = $q.defer(); $http.makeSomeAPICallOrWhatever().then(function (resp) { if(resp = thisOrThat) { doSomeThingsHere(); defer.resolve(); } else { doOtherThingsHere(); defer.resolve(); } }); return defer.promise; } ] });
这将确保状态更改保持要解决的承诺,当API调用完成并且基于从API返回的所有决定时,该承诺被完成。我使用它来检查服务器端的登录状态,然后才允许导航新页面。当API调用解析时,我使用“event.preventDefault()”停止原始导航,然后路由到登录页面(用if state.name!=“login”围绕整个代码块)或允许用户继续通过简单地解决延迟的承诺,而不是试图使用旁路布尔和preventDefault()。
虽然我确信原来的海报很久以来就找出了他们的问题,我真的希望这有助于别人在那里。
编辑
我想我不想误导人。如果你不确定你的状态是否有解析对象,代码应该是什么样子:
$rootScope.$on('$stateChangeStart',toParams) { if (!toState.resolve) { toState.resolve = {} }; toState.resolve.pauseStateChange = [ '$q',function($q) { var defer = $q.defer(); $http.makeSomeAPICallOrWhatever().then(function (resp) { if(resp = thisOrThat) { doSomeThingsHere(); defer.resolve(); } else { doOtherThingsHere(); defer.resolve(); } }); return defer.promise; } ] });
编辑2
为了得到这个工作对于没有解决定义的状态,你需要在app.config中添加:
var $delegate = $stateProvider.state; $stateProvider.state = function(name,definition) { if (!definition.resolve) { definition.resolve = {}; } return $delegate.apply(this,arguments); };
做if(!toState.resolve){toState.resolve = {}};在stateChangeStart似乎不工作,我认为ui路由器不接受解决dict后,它已经初始化。