Tipps und Tricks mit Angular, Teil 10: Mehrdimensionale Navigationsstrukturen

Routenkonfiguration

Dem Router teilt das FlightBookingModule die gewünschte Hierarchie mit ihrer Routenkonfiguration mit. Dazu richtet es eine Route für die FlightBookingComponent ein. Diese erhält über die Auflistung children Child Routes, die auf die FlightSearchComponent und PassengerSearchComponent verweisen:

const FLIGHT_BOOKING_ROUTES: Routes = [
{
path: 'flight-booking',
component: FlightBookingComponent,
children: [
{
path: '',
redirectTo: 'flight-search',
pathMatch: 'full'
},
{
path: 'flight-search',
component: FlightSearchComponent
},
{
path: 'passenger-search',
component: PassengerSearchComponent
}
]
}
];

export let FlightBookingRouterModule =
RouterModule.forChild(FLIGHT_BOOKING_ROUTES);

Die Pfade der Child Routes gelten als Erweiterung der Pfade der übergeordneten Parent-Route. Ein Aufruf der URL flight-booking/flight-search führt beispielsweise dazu, dass der Router die FlightBookingComponent im Platzhalter der Anwendung und die FlightSearchComponent im Platzhalter der FlightBookingComponent aktiviert. Um auch dann eine sinnvolle Antwort liefern zu können, wenn nur die Parent-Route flight-booking aufgerufen wird, definiert die betrachtete Routenkonfiguration eine Standardroute mit leerem Pfad. Diese leitet auf die Route flight-search weiter. Nach dieser Änderung ist noch das Hauptmenü in der AppComponent anzupassen:

<nav class="navbar navbar-default">
<ul class="nav navbar-nav">
<li routerLinkActive="active"><a [routerLink]="['/home']">Home</a></li>
<li routerLinkActive="active"><a [routerLink]="['/flight-booking']">
Flug buchen</a></li>
</ul>
</nav>

<div class="container">
<router-outlet></router-outlet>
</div>

Während der Menüpunkt Home direkt auf die HomeComponent verweist, leitet Flug buchen den Benutzer auf den ersten Unterpunkt der FlugBuchenComponent, nämlich Flug suchen.

Aux Routes

Mit den als Aux Routes bezeichneten Auxiliary Routes (Hilfsrouten) ermöglicht der Router das Einführen mehrerer Platzhalter. Dabei ist jedem von ihnen ein Name zu spendieren. Durch dessen Angabe kann die Anwendung eine Komponente dafür festlegen. Genau genommen hat der bis dato verwendete Platzhalter bereits einen Namen gehabt, zumal Angular standardmäßig die Bezeichnung primary vergibt. Das Konzept hinter Aux Routes bietet zudem die Option, alle Platzhalter unabhängig voneinander mit Inhalten zu füllen:

Schematische Darstellung von Aux Routes (Abb. 4)


Die Tatsache, dass der Platzhalter mit dem Namen aux unter dem Standardplatzhalter positioniert ist, bedeutet übrigens nicht, dass sein Inhalt immer dort eingeblendet wird. CSS ermöglicht die Platzierung überall auf der Seite und sogar das Überblenden des Standardplatzhalters. Auf die Weise lassen sich mit Aux Routes modale Dialoge entwickeln, deren Zustand die URL widerspiegelt. Weitere Anwendungsfälle sind das Einblenden zusätzlicher Informationen sowie das Umsetzen einer Anwendung, die – wie eine Entwicklungsumgebung – aus unterschiedlichen, bis zu einem bestimmten Grad sogar unabhängigen Bereichen besteht. Ein weiteres Beispiel hierfür ist ein Chat, den Entwickler neben dem Arbeitsbereich der Anwendung für Support-Fälle anlegen, oder das Einrichten mehrerer Arbeitsbereiche im Stil weit verbreiteter Dateimanager.

Im Folgenden soll zur Veranschaulichung von Aux Routes eine FlightHistoryComponent zum Einsatz kommen, die Informationen über vergangene Suchanfragen präsentiert. Bei Bedarf wird sie über eine Aux Route aktiviert:

Nutzung einer Aux Route in der Demo-Anwendung (Abb. 5)


Ein Vergleich mit Abb. 6 zeigt, dass der Router Aux Routes unabhängig von der Standardroute aktivieren kann, zumal hier neben der HistoryComponent im Platzhalter aux die HomeComponent im Hauptplatzhalter erscheint.

Aux Routes lassen sich unabhängig von der Standardroute aktivieren (Abb. 6).


Analog zum Standardplatzhalter erhält die AppComponent einen zweiten Platzhalter mit dem Namen aux:

<div class="container">

<div class="row">
<router-outlet></router-outlet>
</div>

<div class="row">
<router-outlet name="aux"></router-outlet>
</div>

</div>

Zusätzlich erhält die Routenkonfiguration einen Eintrag, der sich auf den Platzhalter aux bezieht. Dazu kommt die Eigenschaft outlet zum Einsatz:

let APP_ROUTES: Routes = [
{
path: '',
redirectTo: 'home',
pathMatch: 'full'
},
{
path: 'home',
component: HomeComponent
},
[...]
{
path: 'history',
component: FlightHistoryComponent,
outlet: 'aux'
}
];

Dabei ist zu beachten, dass jede Route einen bestimmten Platzhalter adressiert. Benennt eine Route ihren Platzhalter nicht direkt über die gezeigte Eigenschaft outlet, weist der Router sie dem Standardplatzhalter primary zu.

Den Inhalt für den Standardplatzhalter primary gibt die Anwendung, wie gehabt, über die URL an. Die Komponenten für alle weiteren benannten Platzhalter sind innerhalb runder Klammern in der URL anzuführen. http://localhost:8080/bookings(aux:history;showDetails=true) weist beispielsweise darauf hin, dass die Route bookings im Hauptplatzhalter zu aktivieren ist, und dass die Route history dem Platzhalter mit dem Namen aux eine Komponente verpassen soll. Letztere erhält zur Demonstration einen Parameter showDetails. Zum Generieren solcher URLs bietet sich die Direktive routerLink an:

<li><a [routerLink]="[{outlets: { aux: 'history' }}]">
History einblenden</a></li>
<li><a [routerLink]="[{outlets: { aux: null }}]">History ausblenden</a></li>

Während sie in den vorangegangenen Abschnitten lediglich auf die Route für den Standardplatzhalter verwiesen hat, definiert die Direktive nun ein Objekt, das mit der Eigenschaft outlet auf ein weiteres Objekt verweist. Letzteres bildet die Namen einzelner Platzhalter auf die dafür zu aktivierenden Routen ab. Auf die Weise lassen sich Komponenten für mehrere Platzhalter gleichzeitig aktivieren. Das betrachtete Beispiel zeigt zudem, dass eine Aux Route nicht zwingend aktiv sein muss. Um einen Platzhalter zu leeren, ist lediglich der Wert null zuzuweisen.

Der Vollständigkeit halber zeigt der unten aufgeführte Codeauszug, wie die Anwendung einer Aux Route Parameter übergeben kann. Dazu kommt die gewohnte Schreibweise zum Einsatz, die den Namen der gewünschten Route zusammen mit Parametern in einem Array verstaut.

<li><a [routerLink]="[{outlets: { aux: ['history', 
{showDetail: true}] }}]">History einblenden</a></li>
<li><a [routerLink]="[{outlets: { aux: null }}]">History ausblenden</a></li>