TL;DR: Ab Angular 16 kannst du Route-Parameter direkt über input() bzw. @Input() in deine Komponenten binden – ganz ohne ActivatedRoute. 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.

Angular: Framework für dynamische Single Page Applications
Angular ist eines der beliebtesten Frameworks für moderne Webanwendungen. Erfahre, was Angular ausmacht und wie du damit durchstartest.

🤔 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 Zahl
  • booleanAttribute – 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.

Warum du nur noch TypeScript nutzen solltest
TypeScript bietet dir Typsicherheit, bessere Tooling-Unterstützung und weniger Bugs. Erfahre, warum sich der Umstieg lohnt.

🎯 Vorteile: Warum du umsteigen solltest

  • Weniger Boilerplate – Kein ActivatedRoute, kein subscribe(), kein unsubscribe()
  • 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 mit computed() und effect() 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!

Artikel teilen:Share article:

Wie fandest du diesen Artikel?How did you like this article?