问题描述
为了确定用户的会话是否经过身份验证,我需要在加载第一个路由之前向服务器发出 $http 请求.在加载每个路由之前,身份验证服务会检查用户的状态和路由所需的访问级别,如果用户未通过该路由的身份验证,则会重定向到登录页面.然而,当应用程序第一次加载时,它不知道用户,所以即使他们有一个经过身份验证的会话,它也总是会重定向到登录页面.所以为了解决这个问题,我正在尝试向服务器请求用户状态作为应用程序初始化的一部分.问题是显然 $http 调用是异步的,那么我如何在请求完成之前停止应用程序运行?
In order to determine if a user's session is authenticated, I need to make a $http request to the server before the first route is loaded. Before each route is loaded, an authentication service checks the status of the user and the access level required by the route, and if the user isn't authenticated for that route, it redirects to a login page. When the app is first loaded however, it has no knowledge of the user, so even if they have an authenticated session it will always redirect to the login page. So to fix this I'm trying to make a request to the server for the users status as a part of the app initialisation. The issue is that obviously $http calls are asynchronous, so how would I stop the app running until the request has finished?
总的来说,我对 Angular 和前端开发非常陌生,所以我的问题可能是对 javascript 而不是 Angular 的误解.
I'm very new to Angular and front-end development in general, so my issue maybe a misunderstanding of javascript rather than of Angular.
推荐答案
您可以通过在 routingProvider 中使用 resolve
来实现.
You could accomplish that by using resolve
in your routingProvider.
这允许您在启动控制器之前等待一些承诺得到解决.
This allows you to wait for some promises to be resolved before the controller will be initiated.
引自文档:
resolve - {Object.=} - 应注入控制器的可选依赖关系图.如果这些依赖项中的任何一个是承诺,则路由器将在控制器实例化之前等待它们全部被解析或被拒绝.如果所有 promise 都成功解析,则注入解析的 promise 的值并触发 $routeChangeSuccess 事件.
简单示例
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {templateUrl: 'home.html', controller: 'MyCtrl',resolve: {
myVar: function($q,$http){
var deffered = $q.defer();
// make your http request here and resolve its promise
$http.get('http://example.com/foobar')
.then(function(result){
deffered.resolve(result);
})
return deffered.promise;
}
}}).
otherwise({redirectTo: '/'});
}]);
myVar 然后将被注入到您的控制器,包含承诺数据.
myVar will then be injected to your controller, containing the promise data.
您还可以通过返回无论如何都要注入的服务来避免额外的 DI 参数:
You could also avoid the additional DI parameter by returning a service you were going to inject anyways:
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/', {templateUrl: 'home.html', controller: 'MyCtrl',resolve: {
myService: function($q,$http,myService){
var deffered = $q.defer();
/* make your http request here
* then, resolve the deffered's promise with your service.
*/
deffered.resolve(myService),
return deffered.promise;
}
}}).
otherwise({redirectTo: '/'});
}]);
显然,在执行此类操作时,您必须将请求的结果存储在共享服务中的任何位置.
Obviously, you will have to store the result from your request anywhere in a shared service when doing things like that.
我从 egghead.io
这篇关于AngularJS 应用程序初始化之前的 $http 请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!