TL;DR: Ab Angular 16 kannst du Route-Parameter direkt überinput()bzw.@Input()in deine Komponenten binden – ganz ohneActivatedRoute. Das Ergebnis: weniger Boilerplate, kein manuelles Subscriben und sauberer, reaktiver Code.
Wenn du schon länger mit Angular arbeitest, kennst du das Spiel: Du willst einen Parameter aus der URL lesen und landest sofort bei ActivatedRoute, subscribe() und einer ganzen Menge Boilerplate. Das war jahrelang der Standard – aber seit Angular 16 gibt es einen deutlich eleganteren Weg. In diesem Artikel zeige ich dir, wie du mit input() Route-Parameter direkt in deine Komponente bindest.
🤔 Der klassische Weg: ActivatedRoute
Bisher musstest du für jeden Route-Parameter den ActivatedRoute-Service injizieren und die Parameter manuell subscriben:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-product-detail',
template: `<h1>Produkt {{ productId }}</h1>`
})
export class ProductDetailComponent implements OnInit, OnDestroy {
productId: string = '';
private sub!: Subscription;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
this.productId = params['id'];
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}Das funktioniert, ist aber verbose: Du brauchst den Service, ein Subscription-Management und musst dich um OnDestroy kümmern. Bei mehreren Parametern wird es schnell unübersichtlich.
🚀 Der neue Weg: input() für Route-Parameter
Seit Angular 16 kannst du Route-Parameter direkt als Input binden. Das funktioniert sowohl mit dem klassischen @Input()-Decorator als auch mit dem neuen Signal-basierten input().
Variante 1: @Input() Decorator
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-product-detail',
standalone: true,
template: `<h1>Produkt {{ id }}</h1>`
})
export class ProductDetailComponent {
@Input() id!: string;
}Variante 2: input() Signal (empfohlen)
import { Component, input } from '@angular/core';
@Component({
selector: 'app-product-detail',
standalone: true,
template: `<h1>Produkt {{ id() }}</h1>`
})
export class ProductDetailComponent {
id = input.required<string>();
}Das war's! Kein ActivatedRoute, kein subscribe(), kein OnDestroy. Der Parameter-Name muss dabei mit dem Namen in der Route-Konfiguration übereinstimmen.
✏️ Route-Konfiguration
Die Route wird ganz normal definiert – der Parametername (:id) muss mit dem Input-Namen in der Komponente übereinstimmen:
export const routes: Routes = [
{
path: 'products/:id',
component: ProductDetailComponent
}
];Wenn du die URL /products/42 aufrufst, wird id automatisch auf "42" gesetzt.
⚙️ Setup: Component Input Binding aktivieren
Damit Angular weiß, dass es Route-Parameter an Inputs binden soll, musst du das Feature einmalig aktivieren. Je nach Projektstruktur gibt es zwei Wege:
Standalone Apps (empfohlen)
// app.config.ts
import { provideRouter, withComponentInputBinding } from '@angular/router';
import { routes } from './app.routes';
export const appConfig = {
providers: [
provideRouter(routes, withComponentInputBinding())
]
};NgModule-basierte Apps
// app.module.ts
@NgModule({
imports: [
RouterModule.forRoot(routes, {
bindToComponentInputs: true
})
]
})
export class AppModule {}Ohne diese Konfiguration bleibt der Input undefined – das ist der häufigste Fehler, wenn das Feature nicht funktioniert!
🔧 Transform-Funktionen: Typen automatisch konvertieren
Route-Parameter kommen immer als String aus der URL. Wenn du eine Zahl brauchst, kannst du Transform-Funktionen nutzen, die Angular mitliefert:
import { Component, input } from '@angular/core';
import { numberAttribute } from '@angular/core';
@Component({
selector: 'app-product-detail',
standalone: true,
template: `<h1>Produkt #{{ id() }}</h1>`
})
export class ProductDetailComponent {
// Automatische Konvertierung von string zu number
id = input.required({ transform: numberAttribute });
}Angular bietet unter anderem diese Transform-Funktionen:
numberAttribute– konvertiert den String in eine ZahlbooleanAttribute– konvertiert in einen Boolean- Eigene Funktionen:
transform: (value: string) => value.toUpperCase()
Das ist besonders praktisch, weil du damit TypeScript-Typsicherheit bekommst, ohne manuell casten zu müssen.
🎯 Vorteile: Warum du umsteigen solltest
- Weniger Boilerplate – Kein
ActivatedRoute, keinsubscribe(), keinunsubscribe() - Deep Linking – Parameter sind direkt in der URL, SSR und SEO funktionieren out-of-the-box
- Testbarkeit – Inputs lassen sich in Unit-Tests viel einfacher mocken als
ActivatedRoute - Signal-Integration – Mit
input()bekommst du reaktive Signals, die sich perfekt mitcomputed()undeffect()kombinieren lassen - Konsistenz – Query-Parameter, Path-Parameter und Route-Data nutzen alle denselben Mechanismus
Übrigens: Auch Query-Parameter und Route-Data lassen sich auf dieselbe Art binden. Ein Input namens search greift z.B. automatisch auf den Query-Parameter ?search=... zu.
💡 Fazit
Mit input() für Route-Parameter wird Angular-Code deutlich schlanker. Du sparst dir den ganzen ActivatedRoute-Boilerplate und bekommst reaktive, typsichere Parameter-Bindings quasi geschenkt. Wenn du noch auf dem klassischen Weg unterwegs bist: Jetzt ist der perfekte Zeitpunkt zum Umsteigen!
Mehr Artikel entdecken
Angular input() for Route Parameters: Ditch ActivatedRoute for Good 🚀
Angular 16+ lets you bind route parameters directly via input() – no more ActivatedRoute boilerplate. Here’s how!
Connecting Custom Forms to Google Spreadsheets with Apps Script 📊
Turn any Google Spreadsheet into a free form backend with Google Apps Script – no server needed, with TypeScript type safety and CORS solutions.
Angular input() for Route Parameters: Ditch ActivatedRoute for Good 🚀
Angular 16+ lets you bind route parameters directly via input() – no more ActivatedRoute boilerplate. Here’s how!
Angular: Framework für Single Page Applications🌐
Entdecke Angular, das leistungsstarke Framework von Google, ideal für dynamische Webanwendungen. Erfahre mehr über Komponenten, Datenbindung und Routing! 🌐