Angular Routing & Navigation
Zeit für Multi-Page Apps! Mit Angular Router erstellst du SPAs (Single Page Applications) mit mehreren Seiten. 🗺️
📋 In diesem Artikel lernst du:
- Was Angular Router ist und warum du ihn brauchst
- Router Setup und Konfiguration
- Routes definieren und verschachteln
- Zwischen Seiten navigieren (Links & Programmatisch)
- Route Parameters und Query Parameters
- Wildcard Routes und 404-Seiten
- Route Guards (Schutz für Routen)
- Lazy Loading für bessere Performance
Was ist Angular Router?
Angular Router ermöglicht Navigation zwischen verschiedenen Views/Seiten ohne Page Reload!
Traditionelle Website vs SPA:
Traditionelle Multi-Page Website:
User klickt auf Link
→ Browser lädt NEUE HTML-Seite vom Server
→ Kompletter Page Reload
→ Langsam! ❌
Angular SPA mit Router:
User klickt auf Link
→ Angular Router ändert View (keine Server-Anfrage!)
→ Nur Content wird ausgetauscht
→ Blitzschnell! ✅
Vorteile:
- ✅ Schnelle Navigation (keine Page Reloads)
- ✅ Smooth Transitions
- ✅ App-like Feeling
- ✅ State bleibt erhalten
- ✅ Bookmarkable URLs
Router Setup
Option 1: Bei ng new (Empfohlen)
ng new my-app
? Would you like to add Angular routing? (y/N) y # ✅ JA!
Angular erstellt automatisch:
app-routing.module.ts- Router KonfigurationRouterModuleImport inapp.module.ts<router-outlet>inapp.component.html
Option 2: Nachträglich hinzufügen
ng generate module app-routing --flat --module=app
app-routing.module.ts manuell erstellen:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = []; // Routes kommen hier rein
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
In app.module.ts importieren:
import { AppRoutingModule } from './app-routing.module';
@NgModule({
imports: [
BrowserModule,
AppRoutingModule // ✅ Router aktiviert
],
// ...
})
export class AppModule { }
In app.component.html Router Outlet hinzufügen:
<nav>
<!-- Navigation Links -->
</nav>
<router-outlet></router-outlet> <!-- ✅ Views werden hier geladen -->
<router-outlet> ist der Platzhalter für deine Seiten!
Erste Routes definieren
Komponenten erstellen
ng generate component pages/home
ng generate component pages/about
ng generate component pages/contact
Oder kurz:
ng g c pages/home
ng g c pages/about
ng g c pages/contact
Routes konfigurieren
app-routing.module.ts:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { AboutComponent } from './pages/about/about.component';
import { ContactComponent } from './pages/contact/contact.component';
const routes: Routes = [
{ path: '', component: HomeComponent }, // / (Root)
{ path: 'about', component: AboutComponent }, // /about
{ path: 'contact', component: ContactComponent } // /contact
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Erklärung:
path: ''- Root Route (Homepage)path: 'about'- URL ist/aboutcomponent: AboutComponent- Zeige diese Komponente
URLs:
http://localhost:4200/→ HomeComponenthttp://localhost:4200/about→ AboutComponenthttp://localhost:4200/contact→ ContactComponent
Navigation mit routerLink
HTML Navigation
app.component.html:
<nav class="navbar">
<a routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
Home
</a>
<a routerLink="/about" routerLinkActive="active">
About
</a>
<a routerLink="/contact" routerLinkActive="active">
Contact
</a>
</nav>
<router-outlet></router-outlet>
Erklärung:
routerLink="/"- Navigiert zu dieser Route (NICHThref!)routerLinkActive="active"- CSS Klasse wenn Route aktiv[routerLinkActiveOptions]="{exact: true}"- Exact Match für Root
Styling:
/* app.component.css */
.navbar {
display: flex;
gap: 1rem;
padding: 1rem;
background: #1f2937;
}
.navbar a {
color: #9ca3af;
text-decoration: none;
padding: 0.5rem 1rem;
border-radius: 4px;
transition: all 0.2s;
}
.navbar a:hover {
color: white;
background: #374151;
}
.navbar a.active {
color: white;
background: #3b82f6;
}
✅ Jetzt hast du funktionierende Navigation!
Tipps & Tricks
routerLink vs href
NICHT nutzen:
<!-- ❌ BAD: Normale Links -->
<a href="/about">About</a>
Problem: Page Reload! App-State geht verloren!
Nutzen:
<!-- ✅ GOOD: Router Links -->
<a routerLink="/about">About</a>
Vorteile:
- Kein Page Reload
- State bleibt erhalten
- Schneller!
routerLinkActive Tricks
Exact Match für Root:
<a
routerLink="/"
routerLinkActive="active"
[routerLinkActiveOptions]="{exact: true}"
>
Home
</a>
Ohne exact: true wäre "/" IMMER active (weil jede Route mit "/" startet)!
Multiple CSS Classes:
<a
routerLink="/about"
routerLinkActive="active highlight"
>
About
</a>
CSS Class auf Parent Element:
<li routerLinkActive="active-parent">
<a routerLink="/about">About</a>
</li>
Programmatische Navigation
Im TypeScript Code navigieren
home.component.ts:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-home',
template: `
<div class="home">
<h1>Willkommen auf der Homepage!</h1>
<button (click)="goToAbout()">Über uns</button>
<button (click)="goToContact()">Kontakt</button>
</div>
`
})
export class HomeComponent {
// ✅ Router injizieren
constructor(private router: Router) {}
goToAbout() {
// Navigiere zu /about
this.router.navigate(['/about']);
}
goToContact() {
this.router.navigateByUrl('/contact');
}
}
Zwei Methoden:
navigate(['/path'])- Array-basiertnavigateByUrl('/path')- String-basiert
Nutze navigate() für komplexe Navigation mit Parameters!
Navigation mit Rückgabe-Wert
async navigateToAbout() {
const success = await this.router.navigate(['/about']);
if (success) {
console.log('Navigation erfolgreich!');
} else {
console.log('Navigation fehlgeschlagen!');
}
}
Route Parameters
Dynamic Routes
Problem: Du willst /user/1, /user/2, /user/123 unterstützen.
Lösung: Route Parameters!
app-routing.module.ts:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'user/:id', component: UserDetailComponent } // :id = Parameter
];
:id ist ein Platzhalter für dynamische Werte!
Parameter auslesen
user-detail.component.ts:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-user-detail',
template: `
<div class="user-detail">
<h1>User Detail</h1>
<p>User ID: {{ userId }}</p>
<button (click)="goBack()">Zurück</button>
</div>
`
})
export class UserDetailComponent implements OnInit {
userId: string | null = null;
// ✅ ActivatedRoute injizieren
constructor(
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit() {
// Methode 1: Snapshot (für statische Params)
this.userId = this.route.snapshot.paramMap.get('id');
// Methode 2: Observable (für dynamische Params)
this.route.paramMap.subscribe(params => {
this.userId = params.get('id');
console.log('User ID:', this.userId);
});
}
goBack() {
this.router.navigate(['/']);
}
}
Navigation zu User Detail:
<!-- HTML -->
<a routerLink="/user/123">User 123</a>
<a [routerLink]="['/user', userId]">User Detail</a>
<!-- TypeScript -->
this.router.navigate(['/user', 123]);
Multiple Route Parameters
const routes: Routes = [
{ path: 'product/:category/:id', component: ProductComponent }
];
URL: /product/electronics/42
Auslesen:
ngOnInit() {
const category = this.route.snapshot.paramMap.get('category'); // 'electronics'
const id = this.route.snapshot.paramMap.get('id'); // '42'
}
Query Parameters
Query Parameters sind zusätzliche Daten in der URL: ?filter=active&sort=name
Query Params setzen
HTML:
<a
routerLink="/products"
[queryParams]="{filter: 'active', sort: 'name'}"
>
Active Products
</a>
TypeScript:
this.router.navigate(['/products'], {
queryParams: { filter: 'active', sort: 'name' }
});
URL: /products?filter=active&sort=name
Query Params auslesen
export class ProductListComponent implements OnInit {
constructor(private route: ActivatedRoute) {}
ngOnInit() {
// Snapshot
const filter = this.route.snapshot.queryParamMap.get('filter');
const sort = this.route.snapshot.queryParamMap.get('sort');
// Observable
this.route.queryParamMap.subscribe(params => {
const filter = params.get('filter');
const sort = params.get('sort');
console.log('Filter:', filter, 'Sort:', sort);
});
}
}
Häufige Fehler
Fehler 1: snapshot vs Observable
❌ Problem:
ngOnInit() {
// ❌ Snapshot updated nicht wenn Parameter ändern!
this.userId = this.route.snapshot.paramMap.get('id');
}
Szenario: Navigation von /user/1 zu /user/2 ohne Komponente zu verlassen.
Resultat: userId bleibt 1! ❌
✅ Lösung: Observable nutzen
ngOnInit() {
// ✅ Observable reagiert auf Änderungen!
this.route.paramMap.subscribe(params => {
this.userId = params.get('id');
this.loadUserData(); // Neu laden!
});
}
Faustregel:
- Snapshot: Wenn Parameter sich nie ändert (Komponente wird neu erstellt)
- Observable: Wenn Navigation innerhalb der Komponente möglich ist
Fehler 2: href statt routerLink
❌ Problem:
<a href="/about">About</a> <!-- ❌ Page Reload! -->
✅ Lösung:
<a routerLink="/about">About</a> <!-- ✅ Kein Reload -->
Fehler 3: Router Outlet vergessen
❌ Problem:
<!-- app.component.html -->
<nav>...</nav>
<!-- ❌ Kein <router-outlet>! -->
Resultat: Seiten werden nicht angezeigt!
✅ Lösung:
<nav>...</nav>
<router-outlet></router-outlet> <!-- ✅ Outlet hinzufügen! -->
Wildcard Routes & 404-Seite
404 Not Found Page
Komponente erstellen:
ng generate component pages/not-found
not-found.component.ts:
import { Component } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-not-found',
template: `
<div class="not-found">
<h1>404 - Seite nicht gefunden</h1>
<p>Die gesuchte Seite existiert nicht.</p>
<button (click)="goHome()">Zur Homepage</button>
</div>
`,
styles: [`
.not-found {
text-align: center;
padding: 3rem;
}
h1 {
font-size: 3rem;
color: #ef4444;
}
button {
padding: 0.75rem 1.5rem;
background: #3b82f6;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 1rem;
}
`]
})
export class NotFoundComponent {
constructor(private router: Router) {}
goHome() {
this.router.navigate(['/']);
}
}
Route hinzufügen:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
// ⭐ Wildcard Route MUSS ZULETZT kommen!
{ path: '**', component: NotFoundComponent }
];
** matched ALLE unbekannten Routes!
⚠️ Wichtig: Wildcard Route IMMER ALS LETZTES!
Redirect Routes
Homepage Redirect:
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
// ...
];
Legacy Route Redirect:
const routes: Routes = [
{ path: 'old-about', redirectTo: '/about', pathMatch: 'full' },
{ path: 'about', component: AboutComponent }
];
pathMatch: 'full' bedeutet: Komplette URL muss matchen!
Nested Routes (Verschachtelte Routen)
Beispiel: Dashboard mit Sub-Pages
/dashboard → Dashboard Overview
/dashboard/stats → Dashboard Stats
/dashboard/profile → Dashboard Profile
Komponenten erstellen:
ng g c pages/dashboard
ng g c pages/dashboard/stats
ng g c pages/dashboard/profile
Routes:
const routes: Routes = [
{ path: '', component: HomeComponent },
{
path: 'dashboard',
component: DashboardComponent,
children: [ // ⭐ Verschachtelte Routes
{ path: '', redirectTo: 'stats', pathMatch: 'full' },
{ path: 'stats', component: StatsComponent },
{ path: 'profile', component: ProfileComponent }
]
}
];
dashboard.component.html:
<div class="dashboard">
<h1>Dashboard</h1>
<nav class="sub-nav">
<a routerLink="stats" routerLinkActive="active">Stats</a>
<a routerLink="profile" routerLinkActive="active">Profile</a>
</nav>
<!-- ⭐ Nested Router Outlet für Children -->
<router-outlet></router-outlet>
</div>
Wichtig: Child-Komponenten brauchen eigenes <router-outlet>!
Route Guards
Guards schützen Routes vor unerlaubtem Zugriff.
Beispiel: User muss eingeloggt sein um Dashboard zu sehen.
Auth Guard erstellen
ng generate guard guards/auth
auth.guard.ts:
import { Injectable } from '@angular/core';
import { CanActivate, Router, UrlTree } from '@angular/router';
import { AuthService } from '../services/auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(
private authService: AuthService,
private router: Router
) {}
canActivate(): boolean | UrlTree {
const isLoggedIn = this.authService.isLoggedIn();
if (isLoggedIn) {
return true; // ✅ Zugriff erlaubt
} else {
// ❌ Redirect zu Login
return this.router.createUrlTree(['/login']);
}
}
}
Guard auf Route anwenden:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'login', component: LoginComponent },
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [AuthGuard] // ⭐ Guard aktiviert!
}
];
Wenn User nicht eingeloggt:
- Versuch zu navigieren nach
/dashboard - Guard checkt:
isLoggedIn()= false - Redirect zu
/login
AuthService (Simple Variante)
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private loggedIn = false;
login(username: string, password: string): boolean {
// In Realität: API Call
if (username === 'admin' && password === 'password') {
this.loggedIn = true;
localStorage.setItem('isLoggedIn', 'true');
return true;
}
return false;
}
logout(): void {
this.loggedIn = false;
localStorage.removeItem('isLoggedIn');
}
isLoggedIn(): boolean {
return this.loggedIn || localStorage.getItem('isLoggedIn') === 'true';
}
}
Andere Guard Typen
CanDeactivate: Verhindert Verlassen der Route (unsaved changes)
export class UnsavedChangesGuard implements CanDeactivate<ComponentWithForm> {
canDeactivate(component: ComponentWithForm): boolean {
if (component.hasUnsavedChanges()) {
return confirm('Du hast ungespeicherte Änderungen. Wirklich verlassen?');
}
return true;
}
}
CanLoad: Verhindert Lazy Loading (später mehr)
Debugging & Troubleshooting
Route wird nicht gefunden
Problem: Komponente wird nicht angezeigt
✅ Check:
- Ist Route in
app-routing.module.tsdefiniert? - Ist
<router-outlet>im Template? - Ist
AppRoutingModuleinapp.module.tsimportiert? - Ist Pfad korrekt geschrieben? (
/aboutnicht/abuot)
Console prüfen:
// In Component
constructor(private router: Router) {
console.log('Current URL:', this.router.url);
}
routerLinkActive funktioniert nicht
Problem: CSS Klasse wird nicht gesetzt
✅ Check:
- Für Root (
/) brauchst du[routerLinkActiveOptions]="{exact: true}" - CSS Klasse existiert im Stylesheet?
Testen:
<a
routerLink="/"
routerLinkActive="active"
[routerLinkActiveOptions]="{exact: true}"
class="test"
>
Home
</a>
Guard blockiert nicht
Problem: Guard lässt alles durch
✅ Check:
- Ist Guard in Route konfiguriert? (
canActivate: [AuthGuard]) - Returned Guard
trueoderfalse? - Ist Guard
@Injectable({ providedIn: 'root' })?
Debuggen:
canActivate(): boolean {
const isLoggedIn = this.authService.isLoggedIn();
console.log('Guard check:', isLoggedIn); // ✅ Debug
return isLoggedIn;
}
Lazy Loading (Performance Boost!)
Lazy Loading lädt Modules/Routes nur wenn gebraucht!
Problem ohne Lazy Loading:
User lädt App
→ ALLE Komponenten werden geladen (100+ KB)
→ Auch Komponenten die User nie sieht!
→ Langsamer Initial Load ❌
Mit Lazy Loading:
User lädt App
→ Nur Homepage wird geladen (20 KB)
→ User navigiert zu /admin
→ JETZT wird Admin-Module geladen (30 KB)
→ Schneller Initial Load! ✅
Feature Module erstellen
ng generate module features/admin --route admin --module app-routing
Angular erstellt automatisch:
admin.module.ts- Feature Moduleadmin-routing.module.ts- Routes für Adminadmin.component.ts- Admin Komponente- Lazy Load Route in
app-routing.module.ts
app-routing.module.ts:
const routes: Routes = [
{ path: '', component: HomeComponent },
{
path: 'admin',
loadChildren: () => import('./features/admin/admin.module').then(m => m.AdminModule)
}
];
loadChildren lädt Module lazy!
Vorteile:
- ✅ Schnellerer Initial Load
- ✅ Kleinere Bundle Size
- ✅ Code Splitting
- ✅ Bessere Performance
Tipps & Tricks
Router Best Practices
1. Nutze routerLink, nicht href:
<!-- ✅ GOOD -->
<a routerLink="/about">About</a>
<!-- ❌ BAD -->
<a href="/about">About</a>
2. Relative vs Absolute Paths:
<!-- Absolute (from Root) -->
<a routerLink="/dashboard/stats">Stats</a>
<!-- Relative (from current route) -->
<a routerLink="stats">Stats</a>
<a routerLink="../profile">Profile</a>
3. Array Syntax für komplexe Pfade:
// ✅ GOOD: Type-safe
this.router.navigate(['/user', userId, 'edit']);
// ⚠️ OK: String concat
this.router.navigateByUrl(`/user/${userId}/edit`);
4. Query Params behalten:
this.router.navigate(['/products'], {
queryParamsHandling: 'preserve' // ✅ Params bleiben erhalten
});
5. Fragment für Anchor Links:
this.router.navigate(['/about'], {
fragment: 'team' // → /about#team
});
Navigation Testen
Prüfe ob Navigation funktioniert hat:
const success = await this.router.navigate(['/about']);
console.log('Navigation success:', success);
Aktuelle Route herausfinden:
constructor(private router: Router) {
console.log('Current URL:', this.router.url);
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
console.log('Navigated to:', event.url);
}
});
}
Komplettes Beispiel: Blog App
Routes:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'blog', component: BlogListComponent },
{ path: 'blog/:slug', component: BlogPostComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{ path: '**', component: NotFoundComponent }
];
blog-list.component.ts:
import { Component } from '@angular/core';
interface BlogPost {
slug: string;
title: string;
excerpt: string;
}
@Component({
selector: 'app-blog-list',
template: `
<div class="blog-list">
<h1>Blog Posts</h1>
<div class="posts">
<article *ngFor="let post of posts" class="post-card">
<h2>{{ post.title }}</h2>
<p>{{ post.excerpt }}</p>
<a [routerLink]="['/blog', post.slug]" class="read-more">
Weiterlesen →
</a>
</article>
</div>
</div>
`,
styles: [`
.post-card {
padding: 1.5rem;
border: 1px solid #e5e7eb;
border-radius: 8px;
margin-bottom: 1rem;
}
.read-more {
color: #3b82f6;
text-decoration: none;
font-weight: 600;
}
`]
})
export class BlogListComponent {
posts: BlogPost[] = [
{ slug: 'angular-basics', title: 'Angular Basics', excerpt: 'Lerne Angular Grundlagen...' },
{ slug: 'angular-routing', title: 'Angular Routing', excerpt: 'Navigation in Angular...' },
{ slug: 'angular-forms', title: 'Angular Forms', excerpt: 'Forms in Angular...' }
];
}
blog-post.component.ts:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
interface BlogPost {
slug: string;
title: string;
content: string;
date: string;
}
@Component({
selector: 'app-blog-post',
template: `
<article class="blog-post" *ngIf="post; else notFound">
<button (click)="goBack()" class="back-btn">← Zurück</button>
<h1>{{ post.title }}</h1>
<p class="date">{{ post.date }}</p>
<div class="content">
{{ post.content }}
</div>
<div class="navigation">
<button (click)="previousPost()" [disabled]="!hasPrevious()">
← Vorheriger Post
</button>
<button (click)="nextPost()" [disabled]="!hasNext()">
Nächster Post →
</button>
</div>
</article>
<ng-template #notFound>
<div class="not-found">
<h1>Post nicht gefunden</h1>
<button (click)="goBack()">Zurück zur Blog-Liste</button>
</div>
</ng-template>
`
})
export class BlogPostComponent implements OnInit {
post: BlogPost | null = null;
allPosts: BlogPost[] = [
{ slug: 'angular-basics', title: 'Angular Basics', content: 'Content...', date: '2025-01-01' },
{ slug: 'angular-routing', title: 'Angular Routing', content: 'Content...', date: '2025-01-15' },
{ slug: 'angular-forms', title: 'Angular Forms', content: 'Content...', date: '2025-01-30' }
];
constructor(
private route: ActivatedRoute,
private router: Router
) {}
ngOnInit() {
this.route.paramMap.subscribe(params => {
const slug = params.get('slug');
this.loadPost(slug);
});
}
loadPost(slug: string | null) {
if (!slug) return;
this.post = this.allPosts.find(p => p.slug === slug) || null;
}
goBack() {
this.router.navigate(['/blog']);
}
hasPrevious(): boolean {
if (!this.post) return false;
const index = this.allPosts.findIndex(p => p.slug === this.post!.slug);
return index > 0;
}
hasNext(): boolean {
if (!this.post) return false;
const index = this.allPosts.findIndex(p => p.slug === this.post!.slug);
return index < this.allPosts.length - 1;
}
previousPost() {
if (!this.post) return;
const index = this.allPosts.findIndex(p => p.slug === this.post!.slug);
if (index > 0) {
this.router.navigate(['/blog', this.allPosts[index - 1].slug]);
}
}
nextPost() {
if (!this.post) return;
const index = this.allPosts.findIndex(p => p.slug === this.post!.slug);
if (index < this.allPosts.length - 1) {
this.router.navigate(['/blog', this.allPosts[index + 1].slug]);
}
}
}
Zusammenfassung
Du hast gelernt:
- ✅ Angular Router ermöglicht Navigation ohne Page Reloads
- ✅ Routes definieren mit
{ path: 'about', component: AboutComponent } - ✅ Navigation mit
routerLink(HTML) undrouter.navigate()(TS) - ✅
<router-outlet>ist Platzhalter für Views - ✅ Route Parameters:
:idfür dynamische Routes - ✅ Query Parameters:
?filter=active&sort=name - ✅
routerLinkActivefür active Link Styling - ✅ Wildcard Routes (
**) für 404-Seiten - ✅ Guards schützen Routes (z.B. Auth)
- ✅ Lazy Loading für bessere Performance
Key Takeaways:
routerLinkstatthrefActivatedRoutefür Parameter- Observable für dynamische Parameter
- Guards für Authorization
- Wildcard Route ZULETZT
Router Setup Cheatsheet:
// 1. Routes definieren
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'user/:id', component: UserComponent },
{ path: '**', component: NotFoundComponent }
];
// 2. HTML Navigation
<a routerLink="/about" routerLinkActive="active">About</a>
// 3. TypeScript Navigation
this.router.navigate(['/user', userId]);
// 4. Parameter auslesen
this.route.paramMap.subscribe(params => {
const id = params.get('id');
});
Routing macht deine App zu einer echten SPA! 🎯
Quiz
📝 Quiz
Was macht <router-outlet>?
📝 Quiz
Wie navigierst du programmatisch zu /about?
📝 Quiz
Wofür nutzt man Route Guards?
Übungen
Übung 1: Multi-Page Portfolio
Erstelle eine Portfolio-Website mit:
- Homepage (
/) - About Page (
/about) - Projects Page (
/projects) - Contact Page (
/contact) - 404 Page
Bonus: Active Link Styling mit routerLinkActive
Übung 2: Product Detail Page
Erstelle:
- Product List (
/products) - Zeigt alle Produkte - Product Detail (
/products/:id) - Zeigt ein Produkt - Navigation zwischen Produkten (Previous/Next Buttons)
Daten:
products = [
{ id: 1, name: 'Laptop', price: 999 },
{ id: 2, name: 'Phone', price: 699 },
{ id: 3, name: 'Tablet', price: 499 }
];
Übung 3: Protected Dashboard
Erstelle:
- Login Page (
/login) - Dashboard (
/dashboard) - Protected mit AuthGuard - Logout Button im Dashboard
Auth Logic:
- Login mit
username: 'admin',password: 'test' - Nach Login redirect zu Dashboard
- Ohne Login kein Zugriff auf Dashboard (Redirect zu Login)
Nächste Schritte
Im nächsten Artikel:
- Reactive Forms
- Form Validation
- Custom Validators
- Dynamic Forms
- Form Arrays
➡️ Weiter zu: Angular Reactive Forms
Routing gemeistert! Zeit für Forms! 🚀
Gut gemacht! 🎉
Du hast "Angular Routing & Navigation - Multi-Page Apps erstellen" abgeschlossen
Artikel bewerten
Bitte einloggen um zu bewerten
Das könnte dich auch interessieren
Angular Reactive Forms - Formulare professionell erstellen
Meistere Reactive Forms in Angular: Form Validation, Custom Validators, Dynamic Forms und Best Practices für robuste Formulare.
Angular HTTP Client & APIs - Backend-Kommunikation
Lerne HTTP Requests mit Angular HttpClient: GET, POST, PUT, DELETE, Error Handling, Interceptors und RxJS Operators für professionelle API-Integration.
Angular Services & Dependency Injection - Logik auslagern
Lerne Services in Angular zu erstellen, Dependency Injection zu verstehen und zentrale Geschäftslogik effizient zu organisieren.