Angular-Routing

Aus Zweites Gehirn, dem persönlichen Wiki
Angular-Routing
TypKonzept
QuellenQuelle - Angular Mastery Workshop
Quelle - Recherche - Angular heute 2026
Erstellt2026-09-26
Aktualisiert2026-09-26
Tagsangular, webentwicklung, routing, navigation

Der Router ordnet URLs Komponenten zu, z.B. /home und /customers. Er navigiert per Link oder aus dem Code, lädt Feature-Module erst bei Bedarf (Lazy Loading), schützt Routen mit Guards und reicht Parameter aus der URL als Strom weiter.

Code-Beispiele aus Quelle - Angular Mastery Workshop (Folie 300–313), von den Folienbildern abgeschrieben (Stand Angular 12).

routerLink navigiert, routerLinkActive setzt eine CSS-Klasse, solange die Route aktiv ist. So lässt sich der aktive Menüpunkt hervorheben (Folie 302):

<mat-toolbar color="primary">
  <img src="../../../../assets/logo/angular.svg" alt="Angular" routerLink="home" />

  Angular Mastery Workshop by Tomas Trajan

  <button mat-flat-button routerLink="home" routerLinkActive="active" color="primary">
    Home
  </button>

  <button mat-flat-button routerLink="customers" routerLinkActive="active" color="primary">
    Customers
  </button>
</mat-toolbar>

Mit dem injizierten Router. Das braucht man meist nach einer Verarbeitung, z.B. nach dem Speichern. Nach einem Klick geht es einfacher mit routerLink im Template (Folie 303):

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-org-home',
  template: `
    <button (click)="navigateToCustomer()">Navigate</button>
  `
})
export class HomeComponent implements OnInit {

  constructor(private router: Router) {}

  ngOnInit() {}

  navigateToCustomer() {
    this.router.navigate(['customers'])
  }
}

Routen konfigurieren

Die Hauptrouten stehen im AppRoutingModule (Folie 304):

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    redirectTo: 'home',            // ohne Pfad ("/") nach home umleiten
    pathMatch: 'full',
  },
  {
    path: 'home',
    loadChildren: () => import('./features/home/home.module').then(m => m.HomeModule),
  },
  {
    path: 'customers',             // Module für diese Routen lazy laden
    loadChildren: () =>
      import('./features/customers/customers.module').then(m => m.CustomersModule),
  },
  {
    path: '**',                    // alles andere nach home; muss als LETZTES stehen
    redirectTo: 'home',
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

Lazy Loading

Lazy Loading verkleinert das Startpaket und beschleunigt den Start. Ausserdem erzwingt es eine saubere Architektur: Ein Service aus einem anderen lazy Feature wäre im Browser gar nicht vorhanden, der Fehler fällt also früh auf (Folie 305). Im Browser sieht man es in den Entwicklerwerkzeugen: Beim Start werden main.js, vendor.js usw. geladen, dazu feature-home-home-module.js, weil Home sofort angezeigt wird. Erst beim Wechsel nach /customers kommt das Paket des CustomerModule dazu (Folie 307–308).

Das lazy geladene Modul hat eigenes Routing mit forChild (Folie 306):

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { CustomersComponent } from './customers.component';
import { CustomerEditorComponent } from './customer-editor/customer-editor.component';
import { CustomerDetailsComponent } from './customer-details/customer-details.component';

const routes: Routes = [
  { path: '', component: CustomersComponent },
  { path: 'details/:id', component: CustomerDetailsComponent },
  { path: 'editor', component: CustomerEditorComponent },
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule],
})
export class CustomersRoutingModule {}

Guards

Guards erlauben oder verhindern den Zugriff auf Routen. Arten: CanActivate, CanActivateChild, CanDeactivate, CanLoad (Folie 309). Beispiel: Nur Admins dürfen Kunden bearbeiten (Folie 310):

class AuthGuard implements CanActivate {

  constructor(private userService: UserService){
  }

  canActivate() {
    return this.userService.isAdmin();
  }
}

const routes: Routes = [
  { path: '', component: CustomersComponent },
  { path: 'details/:id', component: CustomerDetailsComponent },
  { path: 'editor', component: CustomerEditorComponent, canActivate: [AuthGuard] },
];

(Der Guard braucht in echt noch @Injectable(), damit der UserService injiziert werden kann.)

Resolver

Ein Resolver lädt Daten vor der Navigation und verzögert sie, bis das Observable einen Wert liefert (Folie 311):

@Injectable()
export class CustomerResolver implements Resolve<Observable<Customer>> {    // Folie: Csutomer
  constructor(private customerService: CustomerService) {}

  resolve() {
    return this.customerService.loadCustomers();
  }
}

Tipp des Kurses: Resolver möglichst nicht verwenden. Sie verzögern den Seitenwechsel. Besser die Seite sofort zeigen und während des Ladens einen Ladeindikator (Spinner) anzeigen.

Pfad-Parameter

In /customers/details/2 ist die 2 ein Pfad-Parameter. Man liest ihn als Strom aus der ActivatedRoute und macht daraus eine Backend-Anfrage. Das Ergebnis abonniert das Template mit | async (Folie 312–313):

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';

import { Customer } from '../model/customers';
import { CustomersBackendService } from '../services/customers-backend.service';

@Component({
  selector: 'my-org-customer-details',
  // ...
})
export class CustomerDetailsComponent implements OnInit {

  customer: Observable<Customer>;

  constructor(
    private activatedRoute: ActivatedRoute,
    private customersBackendService: CustomersBackendService,
  ) {}

  ngOnInit() {
    this.customer = this.activatedRoute.paramMap.pipe(
      map(paramMap => paramMap.get('id')),
      switchMap(id => this.customersBackendService.get(parseInt(id, 10))),
    );
  }
}

switchMap sorgt dafür, dass bei schnellem Wechsel der ID nur die letzte Antwort zählt (siehe RxJS).

Widerspruch

Kurs: Guards und Resolver als Klassen (implements CanActivate), Lazy Loading über NgModules mit loadChildren und RouterModule.forChild. Heute: Klassen-Guards und -Resolver sind seit v15.2 veraltet. Empfohlen sind funktionale Guards mit inject() (Quelle - Recherche - Angular heute 2026). Standalone-Komponenten lassen sich direkt lazy laden. Ein Beispiel (Einordnung Claude):

export const adminGuard: CanActivateFn = () => inject(UserService).isAdmin();

export const routes: Routes = [
  { path: 'editor', loadComponent: () => import('./customer-editor.component')
      .then(m => m.CustomerEditorComponent), canActivate: [adminGuard] },
];

Verwandt