我有两个服务 - 一个用于存储用户详细信息,另一个用于调用以检索这些详细信息:
userService存储要在整个应用程序中使用的用户详细信息(即注入控制器,服务等)
function userService($log) {
var id = '';
var username = '';
var isAuthenticated = false;
var service = {
id: id,
username: username,
isAuthenticated: isAuthenticated
};
return service;
}
使用authService(希望只有一次)从Web API控制器检索用户详细信息:
function authService($log, $http, userService) {
$log.info(serviceId + ': Inside authService method');
var service = {
getUserDetails: getUserDetails
};
return service;
function getUserDetails() {
$log.info(serviceId + ': Inside getUserDetails method');
return $http.get('api/authentication', { cache: true });
}
}
最初,我在.run块中调用了authService fire,如下所示:
.run(['$log', 'authService', 'userService', function ($log, authService, userService) {
authService.getUserDetails()
.then(querySucceeded);
function querySucceeded(result) {
userService.id = result.data.Id;
userService.username = result.data.username;
}
}]);
但问题是getUserDetails返回的promise在我的控制器被解雇之后才解决,因此对我来说太迟了。用户数据尚未就绪。
然后我查看了$ stateProvider中的resolve选项(对于UI-Router):
.state('dashboard', {
url: '/dashboard',
views: {
header: {
templateUrl: 'app/partials/dashboard/header.template.html',
controller: 'DashboardHeaderController',
controllerAs: 'dashboardHeaderVM',
resolve: {
user: function (authService) {
return authService.getUserDetails();
}
}
}
}
})
假设在解析部分中的promise得到解决后才会呈现视图。这似乎工作正常。
这是我使用返回的用户属性的控制器的(相关部分):
function DashboardHeaderController($log, user) {
var vm = this;
// Bindable members
vm.firstName = user.data.firstName;
}
但是,我有两条路线(更多来路),用户可以导航到其中一条路线。我是否需要在authService的每个州部分都有一个resolve属性?无论服务于哪条路由,我都要激活对authService.getUserDetails的调用,并在此之后为任何路由,控制器等提供它。
有更好的(最佳实践)方法吗?
答案 0 :(得分:1)
不确定更好或最佳做法,但我的方式是plunker。
重点是将resolve
移动到某些父根状态。申请中所有州的祖先:
$stateProvider
.state('root', {
abstract : true,
// see controller def below
controller : 'RootCtrl',
// this is template, discussed below - very important
template: '<div ui-view></div>',
// resolve used only once, but for available for all child states
resolve: {
user: function (authService) {
return authService.getUserDetails();
}
}
})
这是解决的根状态。唯一有决心的国家。这是第一个孩子的例子(任何其他孩子都会以类似的方式定义:
$stateProvider
.state('index', {
url: '/',
parent : 'root',
...
这种方法可以开箱即用。我只想提一下,如果'RootCtrl'
定义如下:
.controller('RootCtrl', function($scope,user){
$scope.user = user;
})
我们应该了解UI-Router继承。参见:
小引用:
请记住,只有嵌套状态的视图时,范围属性才会继承状态链。 范围继承属性没有与嵌套状态和所有做嵌套您的观点(模板)。
完全有可能您有嵌套状态,其模板在您网站中的各种非嵌套位置填充ui-views。在这种情况下,您不能期望在子状态视图中访问父状态视图的范围变量...
可以在此Q & A
中找到更多解释那么,这是什么意思?
我们的根视图只能将已解决的内容传递到子状态 - 如果它们的视图是嵌套的。
例如, $scope.user
只有在嵌套时才会在子状态/ views / $ scope中继承
.state('index', {
url: '/',
parent : 'root',
views: {
'' : { // the root view and its scope is now the ancestor
// so $scope.user is available in every child view
templateUrl: 'layout.html',
controller: 'IndexCtrl'
},
'top@index' : { templateUrl: 'tpl.top.html',},
'left@index' : { templateUrl: 'tpl.left.html',},
'main@index' : { templateUrl: 'tpl.main.html',},
},
检查here
答案 1 :(得分:0)
如果我正确理解你想要在页面加载时,你会在任何控制器或服务请求之前获得用户信息。
我目前的项目中有类似的任务。
为了解决这个问题,我在app bootstapping&amp;之前手动请求了当前的用户信息。将其存储在localStorage
。
然后在app引导后,所有控制器/服务都可以访问当前用户信息。
提示:要在app bootstrap之前获取用户信息,您仍然可以通过手动注入来使用$ http服务:
angular.injector(['ng']).get('$http');