Anfänger162025-01-31

Angular Data Binding - Daten & UI verbinden

Meistere alle Data Binding Arten in Angular: Interpolation, Property Binding, Event Binding und Two-Way Binding mit ngModel.

#angular#data-binding#interpolation#event-binding#ngModel#two-way-binding

Angular Data Binding - Daten & UI verbinden

Data Binding ist die Magie die deine Daten mit dem UI verbindet! Lerne alle 4 Arten von Data Binding in Angular.

📋 In diesem Artikel lernst du:

  • Was Data Binding ist und warum es wichtig ist
  • Interpolation {{ }} - Werte anzeigen
  • Property Binding [] - HTML-Properties setzen
  • Event Binding () - Auf Events reagieren
  • Two-Way Binding [(ngModel)] - Bidirektionale Synchronisation
  • Best Practices für Data Binding

Was ist Data Binding?

Data Binding verbindet deine TypeScript-Daten mit deinem HTML-Template.

Ohne Data Binding (Vanilla JS):

// TypeScript
let userName = 'Max';

// Manuell im DOM updaten
document.getElementById('name').textContent = userName;

Mit Angular Data Binding:

<!-- HTML Template -->
<p>{{ userName }}</p>

Das wars! Angular synchronisiert automatisch! ✨

Die 4 Arten von Data Binding

Angular hat 4 Data Binding Richtungen:

Component (TypeScript)
      ↓ [1. Interpolation {{ }}]
      ↓ [2. Property Binding [property]]
    Template (HTML)
      ↑ [3. Event Binding (event)]
      ↕ [4. Two-Way [(ngModel)]]

Lass uns jede Art im Detail anschauen!

1. Interpolation {{ }} - Werte anzeigen

Die einfachste Form: Zeige Werte im Template.

Basic Interpolation

// component.ts
export class UserComponent {
  userName = 'Max Mustermann';
  age = 25;
  city = 'Berlin';
}
<!-- template.html -->
<h1>Hallo, {{ userName }}!</h1>
<p>Du bist {{ age }} Jahre alt.</p>
<p>Du wohnst in {{ city }}.</p>

Ausgabe:

Hallo, Max Mustermann!
Du bist 25 Jahre alt.
Du wohnst in Berlin.

Ausdrücke in Interpolation

<!-- Berechnungen -->
<p>Nächstes Jahr: {{ age + 1 }}</p>

<!-- String-Konkatenation -->
<p>{{ userName + ' aus ' + city }}</p>

<!-- Ternary Operator -->
<p>Status: {{ age >= 18 ? 'Erwachsen' : 'Minderjährig' }}</p>

<!-- Methoden aufrufen -->
<p>{{ getFullInfo() }}</p>
getFullInfo() {
  return `${this.userName}, ${this.age}, ${this.city}`;
}

Was funktioniert NICHT in Interpolation?

Nicht erlaubt:

<!-- Zuweisungen -->
<p>{{ userName = 'Neu' }}</p>  ❌

<!-- new, typeof, instanceof -->
<p>{{ new Date() }}</p>  ❌

<!-- Increment/Decrement -->
<p>{{ age++ }}</p>  ❌

<!-- Bitweise Operatoren -->
<p>{{ age & 1 }}</p>  ❌

Erlaubt:

<!-- Einfache Ausdrücke -->
<p>{{ age + 1 }}</p>  ✅

<!-- Template-Ausdrücke -->
<p>{{ age > 18 ? 'Adult' : 'Minor' }}</p>  ✅

<!-- Methoden -->
<p>{{ getAge() }}</p>  ✅

2. Property Binding [] - Properties setzen

Property Binding setzt HTML-Element Properties dynamisch.

Basis Property Binding

export class ImageComponent {
  imageUrl = 'https://example.com/image.jpg';
  imageAlt = 'Beschreibung';
  isButtonDisabled = true;
}
<!-- Property Binding mit [] -->
<img [src]="imageUrl" [alt]="imageAlt">

<button [disabled]="isButtonDisabled">
  Klick mich
</button>

<!-- Mehrere Properties -->
<input
  [value]="userName"
  [placeholder]="'Name eingeben'"
  [required]="true">

Class Binding

Einzelne Klasse:

<div [class.active]="isActive">Content</div>

Mehrere Klassen:

<div [class]="{'active': isActive, 'highlight': isHighlighted}">
  Content
</div>

String-basiert:

<div [class]="'btn btn-' + buttonType">Button</div>

TypeScript:

isActive = true;
isHighlighted = false;
buttonType = 'primary';

Style Binding

Einzelner Style:

<p [style.color]="textColor">Farbiger Text</p>
<p [style.font-size.px]="fontSize">Text</p>
<div [style.background-color]="bgColor">Box</div>

Mehrere Styles:

<div [style]="{'color': textColor, 'font-size': fontSize + 'px'}">
  Styled Text
</div>

TypeScript:

textColor = '#ff0000';
fontSize = 16;
bgColor = '#f0f0f0';

Attribute Binding

Für HTML-Attribute (nicht Properties):

<!-- aria-label Attribut -->
<button [attr.aria-label]="buttonLabel">Click</button>

<!-- colspan Attribut -->
<td [attr.colspan]="colSpan">Cell</td>

<!-- data-* Attribute -->
<div [attr.data-id]="userId">Content</div>

Tipps & Tricks

Property vs. Attribute

Wichtiger Unterschied:

Properties = DOM-Objekt Properties

<input [value]="userName">  <!-- Property -->

Attributes = HTML-Attribute

<button [attr.aria-label]="label">  <!-- Attribute -->

Faustregel:

  • Nutze Property Binding wenn möglich
  • Nutze Attribute Binding für aria-, data-, colspan, etc.

Interpolation vs Property Binding

Beide funktionieren für Strings:

<!-- Interpolation -->
<img src="{{ imageUrl }}">

<!-- Property Binding (besser!) -->
<img [src]="imageUrl">

Property Binding ist besser weil:

  • Typ-sicher
  • Performanter
  • Kann Non-String Properties setzen

3. Event Binding () - Auf Events reagieren

Event Binding reagiert auf Benutzer-Interaktionen.

Click Events

export class CounterComponent {
  count = 0;

  increment() {
    this.count++;
  }

  decrement() {
    this.count--;
  }

  reset() {
    this.count = 0;
  }
}
<h2>Counter: {{ count }}</h2>

<button (click)="increment()">+</button>
<button (click)="decrement()">-</button>
<button (click)="reset()">Reset</button>

Event Object übergeben

<input (input)="onInput($event)" placeholder="Type...">
<button (click)="onClick($event)">Click</button>
onInput(event: Event) {
  const input = event.target as HTMLInputElement;
  console.log('Value:', input.value);
}

onClick(event: MouseEvent) {
  console.log('Click Position:', event.clientX, event.clientY);
}

Häufige Events

<!-- Mouse Events -->
<div (click)="onClick()">Click</div>
<div (dblclick)="onDoubleClick()">Double Click</div>
<div (mouseenter)="onMouseEnter()">Hover</div>
<div (mouseleave)="onMouseLeave()">Leave</div>

<!-- Keyboard Events -->
<input (keyup)="onKeyUp($event)">
<input (keydown)="onKeyDown($event)">
<input (keyup.enter)="onEnter()">  <!-- Nur Enter! -->

<!-- Form Events -->
<input (input)="onInput($event)">
<input (change)="onChange($event)">
<input (focus)="onFocus()">
<input (blur)="onBlur()">

<!-- Form Submit -->
<form (submit)="onSubmit($event)">
  <button type="submit">Submit</button>
</form>

Event mit Parameter

<button (click)="delete(user.id)">Delete User</button>
<button (click)="greet('Max')">Greet</button>
delete(userId: number) {
  console.log('Delete user:', userId);
}

greet(name: string) {
  alert(`Hallo ${name}!`);
}

Template Reference Variable

<input #nameInput type="text">
<button (click)="greet(nameInput.value)">
  Greet
</button>
greet(name: string) {
  alert(`Hallo ${name}!`);
}

4. Two-Way Binding [(ngModel)]

Two-Way Binding synchronisiert Daten bidirektional.

FormsModule importieren

Wichtig: Zuerst FormsModule importieren!

// app.module.ts
import { FormsModule } from '@angular/forms';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule  // ← Hinzufügen!
  ],
  // ...
})
export class AppModule { }

ngModel verwenden

export class FormComponent {
  userName = '';
  email = '';
  age = 0;
  isSubscribed = false;
}
<h2>Two-Way Binding Demo</h2>

<!-- Text Input -->
<input [(ngModel)]="userName" placeholder="Name">
<p>Hallo, {{ userName }}!</p>

<!-- Email Input -->
<input type="email" [(ngModel)]="email" placeholder="Email">
<p>Deine Email: {{ email }}</p>

<!-- Number Input -->
<input type="number" [(ngModel)]="age" placeholder="Alter">
<p>Du bist {{ age }} Jahre alt.</p>

<!-- Checkbox -->
<label>
  <input type="checkbox" [(ngModel)]="isSubscribed">
  Newsletter abonnieren
</label>
<p>Abonniert: {{ isSubscribed }}</p>

Das ist die Magie von [(ngModel)]:

  • Änderung im Input → Variable wird aktualisiert
  • Variable ändern → Input wird aktualisiert
  • Alles automatisch synchronisiert!

ngModel ausgeschrieben

Was [(ngModel)] wirklich macht:

<!-- Kurzform -->
<input [(ngModel)]="userName">

<!-- Ist equivalent zu: -->
<input
  [ngModel]="userName"
  (ngModelChange)="userName = $event">

Banana-in-a-Box Syntax: [( )] 🍌📦

Dropdown (Select)

<select [(ngModel)]="selectedCountry">
  <option value="">Land wählen</option>
  <option value="de">Deutschland</option>
  <option value="at">Österreich</option>
  <option value="ch">Schweiz</option>
</select>

<p>Gewählt: {{ selectedCountry }}</p>
selectedCountry = '';

Radio Buttons

<label>
  <input type="radio" [(ngModel)]="gender" value="male">
  Männlich
</label>

<label>
  <input type="radio" [(ngModel)]="gender" value="female">
  Weiblich
</label>

<p>Geschlecht: {{ gender }}</p>
gender = '';

Praktisches Beispiel: Login Form

Lass uns alles kombinieren!

export class LoginComponent {
  // Properties
  email = '';
  password = '';
  rememberMe = false;
  errorMessage = '';
  isLoading = false;

  // Methods
  login() {
    this.isLoading = true;
    this.errorMessage = '';

    // Validierung
    if (!this.email || !this.password) {
      this.errorMessage = 'Bitte fülle alle Felder aus!';
      this.isLoading = false;
      return;
    }

    // Simuliere API-Call
    setTimeout(() => {
      if (this.email === 'test@example.com' && this.password === 'password') {
        alert('Login erfolgreich!');
      } else {
        this.errorMessage = 'Falsche Zugangsdaten!';
      }
      this.isLoading = false;
    }, 1000);
  }

  clearForm() {
    this.email = '';
    this.password = '';
    this.rememberMe = false;
    this.errorMessage = '';
  }
}
<div class="login-form">
  <h2>Login</h2>

  <!-- Error Message -->
  <div *ngIf="errorMessage" class="error">
    {{ errorMessage }}
  </div>

  <!-- Email Input -->
  <div>
    <label>Email:</label>
    <input
      type="email"
      [(ngModel)]="email"
      placeholder="deine@email.de"
      [disabled]="isLoading">
  </div>

  <!-- Password Input -->
  <div>
    <label>Passwort:</label>
    <input
      type="password"
      [(ngModel)]="password"
      placeholder="••••••••"
      [disabled]="isLoading">
  </div>

  <!-- Remember Me -->
  <label>
    <input
      type="checkbox"
      [(ngModel)]="rememberMe"
      [disabled]="isLoading">
    Angemeldet bleiben
  </label>

  <!-- Buttons -->
  <button
    (click)="login()"
    [disabled]="isLoading"
    [class.loading]="isLoading">
    {{ isLoading ? 'Lädt...' : 'Anmelden' }}
  </button>

  <button
    (click)="clearForm()"
    [disabled]="isLoading">
    Zurücksetzen
  </button>

  <!-- Debug Info -->
  <div class="debug">
    <p>Email: {{ email }}</p>
    <p>Password: {{ password }}</p>
    <p>Remember: {{ rememberMe }}</p>
  </div>
</div>

Dieses Beispiel nutzt:

  • ✅ Interpolation {{ }}
  • ✅ Property Binding []
  • ✅ Event Binding ()
  • ✅ Two-Way Binding [(ngModel)]

Häufige Fehler

Fehler 1: ngModel ohne FormsModule

Fehler:

Can't bind to 'ngModel' since it isn't a known property

Lösung:

// app.module.ts
import { FormsModule } from '@angular/forms';

@NgModule({
  imports: [FormsModule],  // ← Hinzufügen!
})

Fehler 2: Interpolation in Attributen

FALSCH:

<img src="{{ imageUrl }}">  <!-- Funktioniert, aber nicht ideal -->

RICHTIG:

<img [src]="imageUrl">  <!-- Property Binding bevorzugen! -->

Fehler 3: Event-Name Tippfehler

FALSCH:

<button (onClick)="doSomething()">  <!-- onClick existiert nicht! -->

RICHTIG:

<button (click)="doSomething()">  <!-- click (lowercase) -->

Fehler 4: $event vergessen

FALSCH:

<input (input)="onInput()">  <!-- Event wird nicht übergeben -->
onInput() {  // Kein Parameter!
  // Wie komme ich an den Wert?
}

RICHTIG:

<input (input)="onInput($event)">
onInput(event: Event) {
  const value = (event.target as HTMLInputElement).value;
}
🎯

Zusammenfassung

Du hast gelernt:

  • ✅ Data Binding verbindet TypeScript mit HTML
  • ✅ Interpolation {{ }} zeigt Werte an
  • ✅ Property Binding [] setzt Element-Properties
  • ✅ Event Binding () reagiert auf Events
  • ✅ Two-Way Binding [(ngModel)] synchronisiert bidirektional
  • ✅ FormsModule nötig für ngModel

Die 4 Binding-Arten:

SyntaxRichtungVerwendung
{{ value }}Component → TemplateWerte anzeigen
[property]="value"Component → TemplateProperties setzen
(event)="handler()"Template → ComponentEvents behandeln
[(ngModel)]="value"↔ BidirektionalForm Inputs

Key Takeaways:

  • Nutze Property Binding statt Interpolation für Attribute
  • $event für Event-Details
  • FormsModule für ngModel importieren
  • Template Reference Variables mit #name
  • Event Modifier: (keyup.enter) für spezifische Keys

Quiz

📝 Quiz

Welche Syntax wird für Two-Way Data Binding verwendet?

📝 Quiz

Was muss importiert werden um ngModel zu nutzen?

Nächste Schritte

Im nächsten Artikel:

  • Structural Directives: *ngIf, *ngFor
  • Attribute Directives: ngClass, ngStyle
  • Custom Directives erstellen

➡️ Weiter zu: Angular Directives

Du meisterst jetzt Data Binding! 🎯

AngularLektion 4 von 10
40% abgeschlossen
Lektion abgeschlossen!

Gut gemacht! 🎉

Du hast "Angular Data Binding - Daten & UI verbinden" abgeschlossen

Artikel bewerten

0.0 (0 Bewertungen)

Bitte einloggen um zu bewerten