Datenfluss in Angular: Von der Eltern- zur Kindkomponente mit @Input


Bei der Entwicklung mit Angular ist es eine bewährte Vorgehensweise, die grafische Oberfläche und die Programmlogik in viele kleine, klar abgegrenzte Komponenten aufzuteilen. Das sorgt nicht nur für mehr Übersichtlichkeit im Code, sondern macht eine Anwendung auch deutlich wartbarer und wiederverwendbarer. Gleichzeitig reduziert sich der Umfang des Codes, der in jeder einzelnen Komponente gepflegt werden musst.

Ein wichtiger Punkt dabei ist der Datenfluss: Eltern-Komponenten geben Daten an ihre Kind-Komponenten weiter. Damit behält man die Kontrolle darüber, wo die Daten liegen, und sorgt dafür, dass jede Komponente nur genau den kleinen Teil tut, wofür sie gedacht ist. Im folgenden Beispielen soll das an einer Liste von Personen demonstriert werden. Die Liste selbst ist eine Angular-Komponente. Anstatt die Personen aber direkt anzuzeigen, hat diese Komponente nur die Aufgabe, die einzelnen Personen-Objekte an untergeordnete Komponenten, die Listenelemente, weiterzugeben. Jede dieser Kind-Komponenten kümmert sich dann darum, genau eine Person korrekt darzustellen.

Benötigt wird zunächst ein passendes Datenmodell. Definiert wird der Typ Person, der einen Vornamen und einen Nachnamen enthält. Dieses Modell wird später verwendet, um die Daten sauber zu strukturieren und typensicher zu verwalten.

export type Person = {
  firstname: string;
  name: string;
};

Im Beispiel übernimmt die ListParentComponent nicht nur die Anzeige der Personenliste, sondern auch das Erzeugen der Personendaten selbst. Dafür wurden in Code zwei Arrays für Vornamen und Nachnamen angelegt. Aus diesen Arrays werden per Zufall Namen kombiniert, um realistisch wirkende Personendaten zu erzeugen. Am Ende sollen insgesamt zwölf zufällige Personen generiert werden. Diese werden später in der Liste angezeigt. Diese Vorgehensweise ist ideal, um das Beispiel mit ausreichend Leben zu füllen, ohne alle Daten manuell einzutragen.

import { Component,  OnInit } from '@angular/core';
import { NgFor} from "@angular/common";
import { Person} from "../models/person.model";

@Component({
  selector: 'app-list-parent',
  standalone: true,
  imports: [NgFor],
  templateUrl: './list-parent.component.html',
  styleUrl: './list-parent.component.scss'
})

export class ListParentComponent implements OnInit  {

  persons: Person[] = [];

  private firstnames: string[] = [
    'John', 'Jane', 'Lea', 'Mike', 'Anna', 'Chris',
    'Sophia', 'David', 'Emma', 'Daniel', 'Olivia', 'Lucas'
  ];

  private lastnames: string[] = [
    'Doe', 'Smith', 'Brown', 'Taylor', 'Wilson', 'Johnson',
    'Martinez', 'Lee', 'Garcia', 'Clark', 'Walker', 'Young'
  ];

  ngOnInit(): void {
    this.generateRandomPersons(12);
  }

  private generateRandomPersons(count: number): void {
    this.persons = Array.from({ length: count }, () => ({
      firstname: this.getRandomItem(this.firstnames),
      name: this.getRandomItem(this.lastnames),
    }));
  }

  private getRandomItem<T>(array: T[]): T {
    return array[Math.floor(Math.random() * array.length)];
  }
}

Im TypeScript-Teil der Komponente stehen die generierten Personendaten jetzt im Array persons zur Verfügung. Um diese im HTML-Template anzuzeigen braucht es nicht viel: Eine einfache Schleife mit *ngFor reicht völlig aus, um alle Einträge der Liste darzustellen.

<h2>Person List</h2>

<div *ngFor="let person of persons">
  {{ person.firstname }} {{ person.name }}
</div>

Damit sind die Grundlagen für die Personenliste gelegt und die Änderungen können implementiert werden. Im nächsten Schritt wird die Darstellung einer einzelnen Person in eine eigene Komponente ausgelagert. Das trennt die Logik sauber von der Präsentation und der Code wird strukturierter und wartbarer.

Stacks Image 183

Die Komponente, die für die Darstellung einer einzelnen Person zuständig ist, erhält den Namen ListChildComponent. Im TypeScript-Teil der Komponente findet sich nur wenig Code. Der zentrale Aspekt ist die mit @Input() beginnende Deklaration. Hier wird die Variable personIn definiert, die es ermöglicht, Daten von einer übergeordneten Komponente an diese Komponente zu übergeben.

import { Component, Input } from '@angular/core';
import { Person } from "../models/person.model";

@Component({
  selector: 'app-list-child',
  standalone: true,
  imports: [],
  templateUrl: './list-child.component.html',
  styleUrl: './list-child.component.scss'
})
export class ListChildComponent {
  @Input() personIn!: Person;
}

Der HTML-Teil der Komponente unterscheidet sich nur geringfügig von den bisherigen Strukturen, die zur Anzeige von Vor- und Nachname einer Person verwendet wurden. Der wesentliche Unterschied besteht darin, dass die Komponente nun ausschließlich mit einer einzelnen Person arbeitet, anstatt eine komplette Liste von Personen zu kennen.

<div class="person-card">
  {{ personIn.firstname }} {{ personIn.name }}
</div>

Die Aufteilung in einzelne Komponenten bietet zudem die Möglichkeit, das Design gezielt anzupassen. Im CSS-Teil der ListChildComponent wird ausschließlich das Erscheinungsbild eines einzelnen Listenelements definiert. Das Layout der übergeordneten Liste bleibt hiervon unberührt, da Liste und Listenelement klar voneinander getrennt und voneinander unabhängig gestaltet sind.

.person-card {
  width: 30%;
  margin: 8px auto;
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 8px;
  background-color: #f9f9f9;
  font-family: Arial, sans-serif;
  text-align: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease;
}

In der ListParentComponent lässt sich die neue Komponente zur Darstellung einzelner Listenelemente nun problemlos einsetzen. Anstatt die Person direkt im HTML darzustellen, wird der ListChildComponent über das @Input()-Property personIn ein entsprechendes Personenobjekt übergeben. Der Name personIn ist nicht optimal gewählt und dient hier lediglich der Verdeutlichung.

Damit die ListChildComponent korrekt funktioniert, muss sie zudem im TypeScript-Code der übergeordneten Listenkomponente importiert werden.

<h2>Person List</h2>

<div *ngFor="let person of persons">
  <app-list-child [personIn]="person"></app-list-child>
</div>

Der @Input-Dekorator in Angular wird verwendet, um Daten von einer übergeordneten Komponente an eine untergeordnete Komponente zu übergeben. Dabei kommt eine Datenbindung zum Einsatz. Das bedeutet, dass bei einer Änderung der Daten der übergeordneten Komponente die Eigenschaft der untergeordneten Komponente automatisch aktualisiert wird, um den neuen Wert widerzuspiegeln. @Input ist aber eine einseitige Datenbindung. Die Daten fließen nur von der übergeordneten (Elternteil) zur untergeordneten (Kind) Komponente.

Stacks Image 185
© 2025 Holger Hinzberg Contact