我已成功实施了此处描述的大部分内容。 https://github.com/colthreepv/angular-login-example
我现在的问题是,当我的祖父解析执行时,我的登录服务中的stateChangeStart事件处理程序似乎还没有注册。当我最初加载页面时,事件处理程序永远不会触发,它只会在我加载第一个状态后再次更改状态时触发。这使我在注册登录服务中的stateChangeStart处理程序之前执行了我的决定。我可以做些什么来确保在我的根状态解析执行时已注册事件处理程序?
全球应用路线和决心:
.state('app', {
abstract: true,
templateUrl: 'vassets/partials/partial-nav.html',
resolve: {
'login': ['loginService','$q', '$http', function (loginService, $q, $http) {
loginService.pendingStateChange;
var roleDefined = $q.defer();
/**
* In case there is a pendingStateChange means the user requested a $state,
* but we don't know yet user's userRole.
*
* Calling resolvePendingState makes the loginService retrieve his userRole remotely.
*/
if (loginService.pendingStateChange) {
return loginService.resolvePendingState($http.get('/session'));
} else {
roleDefined.resolve();
}
return roleDefined.promise;
}]
}
})
我的登录服务看起来像这样(处理程序是由服务底部的managePermissions()调用设置的):
/*global define */
'use strict';
define(['angular'], function(angular) {
/* Services */
angular.module('myApp.services', [])
.provider('loginService', function () {
var userToken = localStorage.getItem('userToken'),
errorState = 'app.error',
logoutState = 'app.home';
this.$get = function ($rootScope, $http, $q, $state, AUTH_EVENTS) {
/**
* Low-level, private functions.
*/
var managePermissions = function () {
// Register routing function.
$rootScope.$on('$stateChangeStart', function (event, to, toParams, from, fromParams) {
if (wrappedService.userRole === null) {
wrappedService.doneLoading = false;
wrappedService.pendingStateChange = {
to: to,
toParams: toParams
};
return;
}
if (to.accessLevel === undefined || to.accessLevel.bitMask & wrappedService.userRole.bitMask) {
angular.noop(); // requested state can be transitioned to.
} else {
event.preventDefault();
$rootScope.$emit('$statePermissionError');
$state.go(errorState, { error: 'unauthorized' }, { location: false, inherit: false });
}
});
};
/**
* High level, public methods
*/
var wrappedService = {
loginHandler: function (data, status, headers, config) {
// update user
angular.extend(wrappedService.user, data.user);
wrappedService.isLogged = true;
wrappedService.userRole = data.user.roles[0].roleName;
$rootScope.$broadcast(AUTH_EVENTS.loginSuccess);
$rootScope.currentUser = data.user;
return data.user;
},
loginUser: function (httpPromise) {
httpPromise.success(this.loginHandler);
},
resolvePendingState: function (httpPromise) {
var checkUser = $q.defer(),
self = this,
pendingState = self.pendingStateChange;
httpPromise.success(
function success(httpObj) {
if (!httpObj.user) {
getLoginData();
}
else {
self.loginHandler(httpObj);
}
}
);
httpPromise.then(
function success(httpObj) {
self.doneLoading = true;
if (pendingState.to.accessLevel === undefined || pendingState.to.accessLevel.bitMask & self.userRole.bitMask) {
checkUser.resolve();
} else {
checkUser.reject('unauthorized');
}
},
function reject(httpObj) {
checkUser.reject(httpObj.status.toString());
}
);
self.pendingStateChange = null;
return checkUser.promise;
},
/**
* Public properties
*/
userRole: null,
user: {},
isLogged: null,
pendingStateChange: null,
doneLoading: null
};
managePermissions();
return wrappedService;
};
})
});