Ich schreibe eine kleine AngularJS-App mit einer Anmeldeansicht und einer Hauptansicht, die wie folgt konfiguriert sind:
$routeProvider
.when('/main' , {templateUrl: 'partials/main.html', controller: MainController})
.when('/login', {templateUrl: 'partials/login.html', controller: LoginController})
.otherwise({redirectTo: '/login'});
Mein LoginController überprüft die Benutzer / Pass-Kombination und legt eine Eigenschaft für $ rootScope fest, die Folgendes widerspiegelt:
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.";
}
}
Alles funktioniert, aber wenn ich darauf zugreife http://localhost/#/main
, umgehe ich den Anmeldebildschirm. Ich wollte etwas schreiben wie "Wenn sich die Route ändert, wenn $ rootScope.loggedUser null ist, leiten Sie zu / login um".
...
... warten. Kann ich mir Routenänderungen irgendwie anhören? Ich werde diese Frage trotzdem posten und weiter suchen.
Antworten:
Nach einigem Durchstöbern der Dokumentation und des Quellcodes habe ich es geschafft. Vielleicht ist dies für jemand anderen nützlich?
Ich habe meiner Modulkonfiguration Folgendes hinzugefügt:
Das eine, was seltsam erscheint, ist, dass ich den Teilnamen (
login.html
) testen musste, weil das "nächste" Route-Objekt keine URL oder etwas anderes hatte. Vielleicht gibt es einen besseren Weg?quelle
Hier ist möglicherweise eine elegantere und flexiblere Lösung mit der Konfigurationseigenschaft "Auflösen" und "Versprechungen", die das eventuelle Laden von Daten auf das Routing und die Routingregeln in Abhängigkeit von den Daten ermöglichen.
Sie geben eine Funktion in 'Auflösen' in der Routing-Konfiguration an und führen in der Funktion Laden und Überprüfen von Daten alle Weiterleitungen durch. Wenn Sie Daten laden müssen, geben Sie ein Versprechen zurück. Wenn Sie eine Umleitung durchführen müssen, lehnen Sie das Versprechen vorher ab. Alle Details finden Sie auf den Dokumentationsseiten $ routerProvider und $ q .
Für russischsprachige Leute gibt es einen Beitrag auf habr " Вариант условного раутинга в AngularJS ".
quelle
ui.router
verwendet wird, verwenden Sie$stateProvider
anstelle von$routeProvider
.Ich habe versucht, das gleiche zu tun. Ich habe nach der Arbeit mit einem Kollegen eine andere einfachere Lösung gefunden. Ich habe eine Uhr aufgestellt
$location.path()
. Das macht den Trick. Ich fange gerade an, AngularJS zu lernen und finde, dass dies sauberer und lesbarer ist.quelle
Eine andere Möglichkeit, die Anmeldeumleitung zu implementieren, besteht darin, Ereignisse und Interceptors wie hier beschrieben zu verwenden . In diesem Artikel werden einige zusätzliche Vorteile beschrieben, z. B. das Erkennen, wann eine Anmeldung erforderlich ist, das Einreihen der Anforderungen in die Warteschlange und das erneute Abspielen, sobald die Anmeldung erfolgreich ist.
Sie können Demo eine Arbeits ausprobieren hier und die Demo - Quelle sehen hier .
quelle
1. Legen Sie den globalen aktuellen Benutzer fest.
Legen Sie in Ihrem Authentifizierungsdienst den aktuell authentifizierten Benutzer im Stammbereich fest.
2. Stellen Sie die Authentifizierungsfunktion für jede geschützte Route ein.
3. Überprüfen Sie die Authentifizierung bei jeder Routenänderung.
Alternativ können Sie Berechtigungen für das Benutzerobjekt festlegen und jeder Route eine Berechtigung zuweisen. Überprüfen Sie dann die Berechtigung im Ereignisrückruf.
quelle
if (!user && !next.$$route.public)
next.$$route
? Ich finde nichts in den Angular docs , dass die Argumente geben zu einem beschreiben$routeChangeStart
Ereignis, aber ich nehme annext
undcurr
sind eine Art Standort Objekte? Das$$route
Bit ist schwer zu googeln.$$route
Eigenschaft eine private Variable von Angular ist. Darauf sollten Sie sich nicht verlassen, siehe zum Beispiel: stackoverflow.com/a/19338518/1132101 - Wenn Sie dies tun, wird Ihr Code möglicherweise beschädigt , wenn sich Angular ändert.$route.routes
, um eine Liste zu erstellen (wie in der Antwort von @ thataustin): Holen Sie sich den Pfad für den Standort mitnext.originalPath
und verwenden Sie diesen, um zu indizieren$route.routes
:var auth = $route.routes[next.originalPath]
.So habe ich es gemacht, falls es jemandem hilft:
In der Konfiguration habe ich ein
publicAccess
Attribut für die wenigen Routen festgelegt, die für die Öffentlichkeit zugänglich sein sollen (z. B. Anmelden oder Registrieren):Dann setze ich in einem Ausführungsblock einen Listener für das
$routeChangeStart
Ereignis, zu dem umgeleitet wird, es'/login'
sei denn, der Benutzer hat Zugriff oder die Route ist öffentlich zugänglich:Sie könnten den Zustand offensichtlich von
isLoggedIn
etwas anderem ändern ... nur einen anderen Weg zeigen, dies zu tun.quelle
nextLoc.$$route.publicAccess
übrigens zugreifen.$route.routes[nextLoc.originalPath]
, die keine private Variable verwendet.nextLoc && nextLoc.publicAccess
!Ich mache es mit Abfangjägern. Ich habe eine Bibliotheksdatei erstellt, die der Datei index.html hinzugefügt werden kann. Auf diese Weise haben Sie eine globale Fehlerbehandlung für Ihre Rest-Service-Anrufe und müssen sich nicht um alle Fehler einzeln kümmern. Weiter unten habe ich auch meine Basic-Auth-Login-Bibliothek eingefügt. Dort können Sie sehen, dass ich auch nach dem 401-Fehler suche und an einen anderen Ort umleitung. Siehe lib / ea-basic-auth-login.js
lib / http-error-handle.js
css / http-error-handle.css
index.html
lib / ea-basic-auth-login.js
Fast das gleiche kann für die Anmeldung gemacht werden. Hier haben Sie die Antwort auf die Weiterleitung ($ location.path ("/ login")).
quelle
In Ihrer app.js-Datei:
quelle
Mit dem Angular-UI-Router ist es möglich, zu einer anderen Ansicht umzuleiten . Zu diesem Zweck haben wir die Methode
$state.go("target_view")
. Zum Beispiel:quelle
Wenn Sie keinen Angular-UI-Router verwenden möchten, aber möchten, dass Ihre Controller über RequireJS faul geladen werden, gibt es einige Probleme mit dem Ereignis
$routeChangeStart
bei der Verwendung Ihrer Controller als RequireJS-Module (verzögert geladen) .Sie können nicht sicher sein, ob der Controller geladen wird, bevor er
$routeChangeStart
ausgelöst wird - tatsächlich wird er nicht geladen. Das bedeutet, dass Sie nicht auf Eigenschaften einernext
Route wielocals
oder zugreifen können,$$route
da diese noch nicht eingerichtet sind.Beispiel:
Dies bedeutet, dass Sie dort keine Zugriffsrechte überprüfen können.
Lösung:
Da das Laden des Controllers über das Auflösen erfolgt, können Sie dasselbe mit Ihrer Zugriffskontrollprüfung tun:
Beachten Sie hier, dass
$routeChangeStart
ich anstelle von Ereignis verwende$routeChangeError
quelle
quelle