Single Page Applications mit AngularJS, Teil 5: Routing und Deep-Linking

Werkzeuge  –  0 Kommentare

Das Modul ngRoute unterstützt Entwickler beim Realisieren logischer Seiten innerhalb einer Single Page Application. Das externe Modul UI-Router bietet darüber hinaus Annehmlichkeiten wie verschachtelte Views.

Single Page Applications (SPA) realisieren über eine physische Seite mehrere logische Seiten, sodass der Nutzer ohne (merkbaren) Ladevorgang zwischen einzelnen Seiten wechseln kann. Zur Realisierung derartiger Webanwendungen können Entwickler mit Direktiven wie ngIf oder ngSwitch einzelne Bereiche einer physischen Seite ein- und ausblenden. Als Alternative lassen sich Module einsetzen, die diese Aufgabe abstrahieren und zudem Routing beziehungsweise Deep-Linking unterstützen. Greift man auf solche Techniken zurück, erhält jede logische Seite eine URL, über die man sie im Anschluss referenzieren und über einen Verweis als Lesezeichen speichern kann. Außerdem gibt das Konzept dem Benutzer die Option, über die Zurück-Schaltfläche zur zuvor besuchten logischen Seite zurückzukehren.

Dieser Artikel zeigt zunächst, wie Entwickler mit dem Modul ngRoute, das Bestandteil von AngularJS ist, Routing und Deep-Linking realisieren können. Danach ist der Einsatz des freien externen Moduls UI-Router als Alternative Thema.

Artikelreihe "Single Page Applications mit AngularJS"

Artikel 1: Erste Schritte
Artikel 2: Konzepte näher betrachtet
Artikel 3: Unit-Testing
Artikel 4: Validieren und Internationalisierung
Artikel 5: Routing und Deep-Linking

Das Modul ngRoute, das sich im Lieferumfang von AngularJS befindet, ermöglicht das Definieren sogenannter Routen. Über sie legen Entwickler fest, welche logische Seite innerhalb einer physischen Seite anzuzeigen ist. Auf den ersten Blick sieht eine Route wie ein Teil einer URL aus. Allerdings wird sie im Hash-Fragment der URL der betroffenen Single Page Application platziert. Nachfolgend finden sich drei Beispiele für das Nutzen von Routen einer derartigen Seite:

http://.../Flug/RoutingSample#/passagiere
http://.../Flug/RoutingSample#/passagiere/info
http://.../Flug/RoutingSample#/passagiere/1

Abhängig von den Angaben im Hash-Fragment blendet AngularJS eine von mehreren logischen Seiten innerhalb der adressierten physischen Seite ein. Da die Route über die URL angegeben wird, erzeugt der Browser dafür einen Eintrag in seiner History. Das führt dazu, dass der Benutzer mit der Zurück- Schaltfläche zu bereits besuchten logischen Seiten springen und ein Bookmark erstellen kann. Wie das letzte der vorangegangenen Beispiele andeutet, kann eine Route auch Parameter enthalten. Im betrachteten Fall gibt er an, welcher Passagier anzuzeigen ist. Um auf einen über das Routing bereitgestellten Parameter zugreifen zu können, lässt der Entwickler in den Controller den Service $routeParams injizieren. Dabei handelt es sich um ein einfaches JavaScript-Objekt, das pro Routing-Parameter eine Eigenschaft aufweist. Der Controller DetailCtrl im betrachteten Listing veranschaulicht dies anhand des Routing-Parameters id, der in der Route /passagiere/:id angegeben wurde.

Zur Nutzung von ngRoute bindet der Entwickler das Skript angular-route.js ein und referenziert es beim Erstellen des Moduls für die Anwendung.

<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.js"></script>

<script>

var app = angular.module("routing", ['ngRoute']);

app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/passagiere, {
templateUrl: '/partials/routing.list.html',
controller: 'ListCtrl'
})
.when('/passagiere/info', {
templateUrl: '/partials/routing.info.html',
controller: 'InfoCtrl'
})
.when('/passagiere/:id', {
templateUrl: '/partials/routing.details.html',
controller: 'DetailCtrl'
})
.otherwise({
redirectTo: '/passagiere'
});
}]);

app.controller("ListCtrl", ["$scope", function ($scope) {
$scope.passagiere = [
{ id: 1, vorname: "Max", nachname: "Muster",
passagierStatus: "B" },
{ id: 2, vorname: "Susi", nachname: "Sorglos",
passagierStatus: "A" },
{ id: 3, vorname: "Reiner", nachname: "Zufall",
passagierStatus: "B" },
{ id: 4, vorname: "Hans-Peter", nachname: "Grahsl",
passagierStatus: "A" }
];
}]);

app.controller("DetailCtrl", ["$scope", "$routeParams", function ($scope, $routeParams) {
$scope.id = $routeParams.id;

}]);

app.controller("InfoCtrl", ["$scope", function ($scope) {
$scope.info = "Hallo Welt!";
}]);
</script>

Obenstehendes Beispiel demonstriert das und zeigt zudem, wie Entwickler unter Verwendung der Funktion config, die AngularJS auf Modulebene bereitstellt, Routen konfigurieren können. config nimmt eine Funktion mit dem nötigen Konfigurationscode entgegen. Sie bekommt Abhängigkeiten injziert, wie unter AngularJS üblich. Um später Probleme mit der Minification zu verhindern, akzeptiert config auch ein Array mit den Namen der Abhängigkeiten und einer Funktion. Auf die Weise lässt das Beispiel den von ngRoute bereitgestellten $routeProvider injizieren.