J'écris une petite application AngularJS qui a une vue de connexion et une vue principale, configurées comme suit:
$routeProvider
.when('/main' , {templateUrl: 'partials/main.html', controller: MainController})
.when('/login', {templateUrl: 'partials/login.html', controller: LoginController})
.otherwise({redirectTo: '/login'});
Mon LoginController vérifie la combinaison utilisateur / passe et définit une propriété sur $ rootScope reflétant ceci:
function LoginController($scope, $location, $rootScope) {
$scope.attemptLogin = function() {
if ( $scope.username == $scope.password ) { // test
$rootScope.loggedUser = $scope.username;
$location.path( "/main" );
} else {
$scope.loginError = "Invalid user/pass.";
}
}
Tout fonctionne, mais si j'y accède, http://localhost/#/main
je finis par contourner l'écran de connexion. Je voulais écrire quelque chose comme "chaque fois que l'itinéraire change, si $ rootScope.loggedUser est nul, puis rediriger vers / login"
...
... attendre. Puis-je écouter les changements d'itinéraire en quelque sorte? Je vais quand même poster cette question et continuer à chercher.
Réponses:
Après avoir plongé dans la documentation et le code source, je pense que je l'ai fait fonctionner. Peut-être que cela sera utile pour quelqu'un d'autre?
J'ai ajouté ce qui suit à la configuration de mon module:
La seule chose qui semble étrange est que j'ai dû tester le nom partiel (
login.html
) parce que l'objet "suivant" Route n'avait pas d'URL ou autre chose. Peut-être y a-t-il une meilleure façon?la source
Voici peut-être une solution plus élégante et flexible avec une propriété de configuration «résoudre» et des «promesses» permettant un éventuel chargement de données sur le routage et des règles de routage en fonction des données.
Vous spécifiez une fonction dans «résoudre» dans la configuration de routage et dans la fonction charger et vérifier les données, faire toutes les redirections. Si vous devez charger des données, vous retournez une promesse, si vous devez faire une redirection - rejetez la promesse avant cela. Tous les détails peuvent être trouvés sur les pages de documentation $ routerProvider et $ q .
Pour les russophones, il y a un article sur habr " Вариант условного раутинга в AngularJS ".
la source
ui.router
est utilisé, utilisez à la$stateProvider
place de$routeProvider
.J'ai essayé de faire de même. Je suis venu avec une autre solution plus simple après avoir travaillé avec un collègue. J'ai installé une montre
$location.path()
. Ça fait l'affaire. Je commence tout juste à apprendre AngularJS et je trouve cela plus propre et plus lisible.la source
Une autre manière de mettre en œuvre la redirection de connexion consiste à utiliser les événements et les intercepteurs comme décrit ici . L'article décrit certains avantages supplémentaires tels que la détection d'une connexion requise, la mise en file d'attente des demandes et leur relecture une fois la connexion réussie.
Vous pouvez essayer une démonstration de travail ici et voir la source de démonstration ici .
la source
1. Définissez l'utilisateur actuel global.
Dans votre service d'authentification, définissez l'utilisateur actuellement authentifié sur la portée racine.
2. Définissez la fonction d'authentification sur chaque itinéraire protégé.
3. Vérifiez l'authentification à chaque changement d'itinéraire.
Vous pouvez également définir des autorisations sur l'objet utilisateur et attribuer à chaque route une autorisation, puis vérifier l'autorisation dans le rappel d'événement.
la source
if (!user && !next.$$route.public)
next.$$route
? Je ne trouve rien dans les documents angulaires qui décrivent les arguments donnent à un$routeChangeStart
événement, mais je supposenext
etcurr
sont une sorte d'objets de localisation? Le$$route
bit est difficile à google.$$route
propriété est une variable privée d'Angular. Vous ne devriez pas vous y fier, voir par exemple: stackoverflow.com/a/19338518/1132101 - si vous le faites, votre code pourrait se casser lorsque Angular change.$route.routes
de construire une liste (comme dans la réponse de @ thataustin): obtenir le chemin pour l'emplacement avecnext.originalPath
et l' utiliser pour l' indice$route.routes
:var auth = $route.routes[next.originalPath]
.Voici comment je l'ai fait, au cas où cela aiderait quelqu'un:
Dans la configuration, j'ai défini un
publicAccess
attribut sur les quelques routes que je souhaite ouvrir au public (comme la connexion ou l'enregistrement):puis dans un bloc d'exécution, j'ai mis un écouteur sur l'
$routeChangeStart
événement qui redirige vers à'/login'
moins que l'utilisateur ait accès ou que la route soit accessible au public:Vous pouvez évidemment changer la condition de
isLoggedIn
n'importe quoi d'autre ... montrant simplement une autre façon de le faire.la source
nextLoc.$$route.publicAccess
btw.$route.routes[nextLoc.originalPath]
, qui n'utilise pas de variable privée.nextLoc && nextLoc.publicAccess
!Je le fais en utilisant des intercepteurs. J'ai créé un fichier de bibliothèque qui peut être ajouté au fichier index.html. De cette façon, vous aurez une gestion globale des erreurs pour vos appels de service de repos et vous n'aurez pas à vous soucier de toutes les erreurs individuellement. Plus bas, j'ai également collé ma bibliothèque de connexion d'authentification de base. Là, vous pouvez voir que je vérifie également l'erreur 401 et que je redirige vers un autre emplacement. Voir lib / ea-basic-auth-login.js
lib / http-error-handling.js
css / http-error-handling.css
index.html
lib / ea-basic-auth-login.js
Presque la même chose peut être faite pour la connexion. Ici, vous avez la réponse à la redirection ($ location.path ("/ login")).
la source
Dans votre fichier app.js:
la source
Il est possible de rediriger vers une autre vue avec angular-ui-router . Pour cela, nous avons la méthode
$state.go("target_view")
. Par exemple:la source
Si vous ne souhaitez pas utiliser angular-ui-router, mais souhaitez que vos contrôleurs soient chargés paresseusement via RequireJS, il y a quelques problèmes avec l'événement
$routeChangeStart
lors de l'utilisation de vos contrôleurs en tant que modules RequireJS (chargés paresseusement).Vous ne pouvez pas être sûr que le contrôleur sera chargé avant d'
$routeChangeStart
être déclenché - en fait, il ne sera pas chargé. Cela signifie que vous ne pouvez pas accéder aux propriétés de l'next
itinéraire commelocals
ou$$route
parce qu'elles ne sont pas encore configurées.Exemple:
Cela signifie que vous ne pouvez pas y vérifier les droits d'accès.
Solution:
Comme le chargement du contrôleur se fait via résoudre, vous pouvez faire de même avec votre contrôle de contrôle d'accès:
Notez ici qu'au lieu d'utiliser l'événement que
$routeChangeStart
j'utilise$routeChangeError
la source
la source