Angular Endlosschleife mit UI-Router
Das Problem, das ich ursprünglich zu lösen versuchte, bestand darin, einen Benutzer zur Anmeldeseite umzuleiten, wenn er nicht angemeldet ist, und umgekehrt.
Ich habe dies mit dem folgenden Code getan
.run(function($rootScope, $http, AppService, $state) {
$rootScope.$on('application:refreshtoken', function(rootScope, token) {
if(token) {
$http.defaults.headers.common['X-Auth-Token'] = token;
AppService.setAuthToken(token);
AppService.resetLoginTimeout();
}
});
$rootScope.$on('$stateChangeSuccess', function() {
$http.get('/api/heartbeat');
});
// This is the really pertinent bit...
$rootScope.$on('$stateChangeStart', function(e, toState) {
if(toState.name === 'login') {
if(AppService.getIsLoggedIn()) {
e.preventDefault();
$state.go(AppService.getRedirectPage());
}
} else {
if(!AppService.getIsLoggedIn()) {
e.preventDefault();
$state.go('login');
}
}
});
});
AppService.factory('AppService', ['$rootScope', 'locker', '$http', '$state',
function ($rootScope, locker, $http, $state) {
var _isLoggedIn = locker.get('loggedIn', false),
_authToken = locker.get('authtoken', null),
_roles = locker.get('roles', null),
_permissions = locker.get('permissions', null),
_user = locker.get('user', null),
_userid = locker.get('userid', null),
_userprefs = locker.get('userprefs', null),
_timedout,
_timeoutId,
service = {};
if (_authToken) {
$http.defaults.headers.common['X-Auth-Token'] = _authToken;
}
service.setIsLoggedIn = function (isLoggedIn) {
_isLoggedIn = isLoggedIn;
this.doLogin();
broadcastLogin();
};
service.doLogin = function () {
if (_isLoggedIn) {
locker.put({
loggedIn: _isLoggedIn,
authtoken: _authToken,
roles: _roles,
permissions: _permissions,
user: _user,
userprefs: _userprefs
});
}
};
service.doLogout = function (cb) {
_isLoggedIn = false;
_authToken = null;
_roles = null;
_permissions = null;
_user = null;
_userid = null;
_userprefs = null;
delete $http.defaults.headers.common['X-Auth-Token'];
locker.clean();
cb();
};
service.getIsLoggedIn = function () {
return _isLoggedIn;
};
service.setAuthToken = function (authToken) {
_authToken = authToken;
locker.put({
authtoken: _authToken
});
};
service.getAuthToken = function () {
return _authToken;
};
service.setUserid = function (userid) {
locker.put('userid', userid);
_userid = userid;
};
service.getUserid = function () {
return _userid;
};
service.setUser = function (user) {
_user = user;
};
service.getUser = function () {
return _user;
};
service.setRoles = function (roles) {
_roles = roles;
};
service.getRoles = function () {
return _roles;
};
service.setPermissions = function (permissions) {
_permissions = permissions;
};
service.getPermissions = function () {
return _permissions;
};
service.setUserPreferences = function (prefs) {
_userprefs = prefs;
};
service.getUserPreferences = function () {
return _userprefs;
};
service.resetLoginTimeout = function () {
if (_timeoutId) {
clearTimeout(_timeoutId);
}
_timeoutId = setTimeout(function () {
$rootScope.$broadcast('application:logintimeoutwarn');
}, 1000 * 60 * 4);
};
service.setTimedOut = function (timedout) {
_timedout = timedout;
};
service.getTimedOut = function () {
return _timedout;
};
service.extendSession = function () {
$http.get('/api/heartbeat');
};
service.goDefaultUserPage = function () {
var success = false;
if (_userprefs.landingPage) {
$state.go(_userprefs.landingPage);
success = true;
} else {
var permissionRoutes = {
'regimens': 'regimens.do',
'pathways': 'pathways',
'manage.users': 'manageusers.do',
'manage.practices': 'managepractices.do',
'patients': 'patients'
};
_.some(_permissions, function (el) {
var state = $state.get(permissionRoutes[el]);
if (!state.abstract) {
$state.go(state.name);
success = true;
return true;
}
});
}
return success;
};
service.getRedirectPage = function () {
var page = false;
if (_userprefs.landingPage) {
page = _userprefs.landingPage;
} else {
var permissionRoutes = {
'regimens': 'regimens.do',
'pathways': 'pathways',
'manage.users': 'manageusers.do',
'manage.practices': 'managepractices.do',
'patients': 'patients'
};
_.some(_permissions, function (el) {
var state = $state.get(permissionRoutes[el]);
if (!state.abstract) {
page = state.name;
return true;
}
});
}
return page;
};
function broadcastLogin() {
$rootScope.$broadcast('application:loggedinstatus');
}
broadcastLogin();
return service;
}
])
Dieser Code funktioniert hervorragend, bis ich eine ganz bestimmte Reihe von Aktionen durchführe:
EinloggeSchließen Sie die geöffnete Registerkarte oder das geöffnete FensterÖffne einen neuen Tab und gehe zur Anwendung Da ich immer noch in der Anwendung angemeldet bin, habe ich ein Benutzerobjekt und ein gültiges Token, aber ich erhalteerror:infdig Infinite $digest Loop
. Es löst sich schließlich auf und wechselt in den richtigen Zustand. Es dauert jedoch eine Weile und der Pfad flackert (ich kann bei Bedarf ein Video posten).
Ich habe versucht mit$location.path
Anstatt von$state.go
in dem$rootScope.$on('$stateChangeSuccess')
Rückruf, aber das Problem bleibt bestehen.
Dies beeinträchtigt die Funktionsweise der Anwendung nicht wirklich, ist aber ärgerlich. Ich möchte meinen Schließfachspeicher auch nicht wirklich in Sitzungsspeicher ändern, da ich möchte, dass der Benutzer angemeldet bleibt, wenn er den Tab schließt und erneut öffnet.