Angular-Komponenten bestehen aus zwei fundamentalen Teilen: der TypeScript-Klasse, die Daten und Logik verwaltet, und dem HTML-Template, das die Benutzeroberfläche definiert. Binding ist der Mechanismus, der diese beiden Welten verbindet. Ohne Binding wären Komponenten statische Konstrukte ohne jede Interaktivität.
Das Binding-System von Angular unterscheidet sich grundlegend von
klassischem JavaScript mit manueller DOM-Manipulation. Statt imperativer
Befehle wie element.textContent = value oder
element.addEventListener('click', handler) definiert
Angular deklarativ im Template, wie Daten fließen und wie Ereignisse
behandelt werden. Das Framework übernimmt die eigentliche Arbeit der
DOM-Synchronisation.
Diese Abstraktion hat weitreichende Konsequenzen für die Entwicklung. Code wird lesbarer, wartbarer und weniger fehleranfällig. Angular’s Change Detection überwacht automatisch Änderungen und aktualisiert die Darstellung, ohne dass Entwickler jede DOM-Operation manuell implementieren müssen.
Binding funktioniert nur, weil Angular kontinuierlich überwacht, wann sich Daten ändern. Dieser Mechanismus heißt Change Detection und läuft nach einem klaren Prinzip: Bei bestimmten Auslösern prüft Angular den gesamten Komponentenbaum auf Änderungen und synchronisiert das DOM entsprechend.
Die Auslöser für Change Detection sind vielfältig. Jede asynchrone Operation – HTTP-Requests, Timer, Promises – triggert einen Prüfzyklus. Benutzerinteraktionen wie Klicks, Tastatureingaben oder Mausbewegungen ebenfalls. Angular integriert sich dafür tief in die Browser-APIs und überwacht diese Ereignisse automatisch.
Der Ablauf ist klar definiert: Ein Ereignis tritt ein, Angular startet einen Change Detection-Zyklus, alle Komponenten werden geprüft, geänderte Bindungen werden aktualisiert, das DOM wird synchronisiert. Dieser Prozess ist hochoptimiert und läuft so schnell, dass Aktualisierungen für Benutzer nahezu instantan erscheinen.
Angular strukturiert Binding in vier Hauptkategorien, die jeweils unterschiedliche Datenflussrichtungen und Anwendungsfälle abdecken. Diese Kategorisierung ist nicht willkürlich, sondern spiegelt die natürlichen Kommunikationsmuster zwischen Komponente und Template wider.
| Kategorie | Syntax | Datenfluss | Primärer Zweck |
|---|---|---|---|
| Property Binding | [property]="expression" |
Komponente → Template | DOM-Eigenschaften setzen, Komponenteneingaben übertragen |
| Event Binding | (event)="handler()" |
Template → Komponente | Benutzerinteraktionen verarbeiten |
| Two-Way Binding | [(ngModel)]="property" |
Komponente ↔︎ Template | Bidirektionale Synchronisation, Formulareingaben |
| Attribute/Class/Style | [attr.name]="value" |
Komponente → Template | Spezielle DOM-Attribute manipulieren |
Property Binding transportiert Daten von der Komponente ins Template. Event Binding macht das Gegenteil – es leitet Ereignisse vom Template zurück zur Komponente. Two-Way Binding vereint beide Richtungen in einer kompakten Syntax. Die spezialisierten Binding-Formen für Attribute, Klassen und Styles bieten feinkörnige Kontrolle über DOM-Eigenschaften.
Die Syntax mit eckigen Klammern signalisiert Property Binding. Angular wertet den Ausdruck rechts aus und weist das Ergebnis der Eigenschaft links zu. Diese Zuweisung ist reaktiv – ändert sich der Wert in der Komponente, aktualisiert Angular automatisch die DOM-Eigenschaft.
Ein kritisches Verständnis betrifft den Unterschied zwischen HTML-Attributen und DOM-Eigenschaften. HTML-Attribute sind statische Werte im Markup, die die initiale Konfiguration definieren. DOM-Eigenschaften sind dynamische JavaScript-Eigenschaften des Element-Objekts, die sich zur Laufzeit ändern können.
<!-- HTML-Attribut: statisch im Markup -->
<input value="Anfangswert">
<!-- Property Binding: dynamisch aktualisiert -->
<input [value]="currentValue">Wenn ein Benutzer Text in ein Input-Feld tippt, ändert sich die
DOM-Eigenschaft value, das HTML-Attribut value
bleibt jedoch unverändert. Angular bindet an DOM-Eigenschaften, nicht an
Attribute – mit einer Ausnahme, dem speziellen Attribute-Binding, das
später behandelt wird.
Ein einfaches Beispiel demonstriert die Grundlagen:
export class ImageComponent {
imageUrl = 'assets/logo.png';
imageAlt = 'Firmenlogo';
isButtonDisabled = false;
toggleButton() {
this.isButtonDisabled = !this.isButtonDisabled;
}
}Im Template:
<img [src]="imageUrl" [alt]="imageAlt">
<button [disabled]="isButtonDisabled" (click)="toggleButton()">
Aktion ausführen
</button>Angular wertet imageUrl aus und setzt die
src-Eigenschaft des img-Elements. Bei jedem
Click wird isButtonDisabled umgeschaltet, und der Button
reagiert sofort durch Aktivierung oder Deaktivierung.
Angular bietet zwei Wege, Werte ans Template zu binden: Interpolation mit doppelten geschwungenen Klammern und Property Binding mit eckigen Klammern. Beide Mechanismen führen letztlich zum gleichen Ergebnis, unterscheiden sich aber in Lesbarkeit und Anwendungsfall.
<!-- Interpolation: intuitiv für Text -->
<p>Willkommen, {{ userName }}!</p>
<!-- Property Binding: explizit für Eigenschaften -->
<p [textContent]="'Willkommen, ' + userName + '!'"></p>Interpolation eignet sich für Textinhalte und String-Ausgaben. Die Syntax ist kompakt und die Intention klar. Property Binding zeigt seine Stärken bei Nicht-String-Werten wie Zahlen, Booleans oder Objekten. Hier würde Interpolation zu impliziter String-Konvertierung führen, während Property Binding die Typen erhält.
<!-- Interpolation konvertiert zu String -->
<div>Zählerstand: {{ counter }}</div>
<!-- Property Binding erhält den Typ -->
<progress [value]="counter" [max]="maxValue"></progress>Das progress-Element erwartet numerische Werte. Property
Binding übergibt sie direkt, ohne String-Konvertierung. Dies ist nicht
nur semantisch korrekter, sondern auch performanter.
Angular ermöglicht direkten Zugriff auf praktisch jede DOM-Eigenschaft. Dies ist besonders mächtig bei komplexen Elementen wie Media-Playern, wo viele Eigenschaften zur Laufzeit gesteuert werden müssen.
<video
[src]="videoSource"
[currentTime]="startTime"
[playbackRate]="playSpeed"
[muted]="isMuted"
(timeupdate)="updateProgress($event)">
</video>Die Komponente steuert jeden Aspekt des Video-Elements:
export class MediaPlayerComponent {
videoSource = 'assets/demo.mp4';
startTime = 30; // Video startet bei 30 Sekunden
playSpeed = 1.5; // 1.5-fache Geschwindigkeit
isMuted = false;
currentProgress = 0;
updateProgress(event: Event) {
const video = event.target as HTMLVideoElement;
this.currentProgress = (video.currentTime / video.duration) * 100;
// Kapitelmarkierungen bei bestimmten Zeitpunkten
if (video.currentTime >= 45 && video.currentTime <= 46) {
this.showChapterIndicator('Kapitel 2');
}
}
setPlaybackSpeed(speed: number) {
this.playSpeed = speed;
}
private showChapterIndicator(chapter: string) {
console.log(`Jetzt läuft: ${chapter}`);
}
}Die currentTime-Eigenschaft springt zu einer bestimmten
Stelle, playbackRate ändert die Geschwindigkeit,
muted kontrolliert den Ton. Alle Änderungen wirken sofort,
ohne manuelle DOM-Manipulation.
Ein weiteres Beispiel zeigt die Steuerung von Text-Selektion:
<input
[value]="initialValue"
[selectionStart]="5"
[selectionEnd]="10"
(focus)="logFocus()">Beim Fokussieren markiert Angular automatisch die Zeichen 5 bis 10 im Input-Feld. Diese programmatische Kontrolle über Selektion ist mit reinem HTML nicht möglich.
Angular’s Sicherheitsmodell schützt vor Cross-Site-Scripting (XSS) durch automatische Sanitization. Besonders beim Binding von HTML-Inhalten ist dies essentiell, da unsanitisierter Input potentiell schädlichen Code ausführen könnte.
<div [innerHTML]="htmlContent"></div>Angular sanitisiert htmlContent automatisch. Potentiell
gefährliche Elemente wie <script>-Tags oder
Event-Handler werden entfernt. Dies geschieht kontextabhängig – für
HTML-Inhalte gelten andere Regeln als für URLs oder CSS-Styles.
Der DomSanitizer-Service erlaubt explizite Kontrolle
über diesen Prozess:
import { Component } from '@angular/core';
import { DomSanitizer, SafeHtml, SafeResourceUrl } from '@angular/platform-browser';
@Component({
selector: 'app-security-demo',
template: `
<div [innerHTML]="safeHtml"></div>
<iframe [src]="safeVideoUrl" width="560" height="315"></iframe>
`
})
export class SecurityDemoComponent {
rawHtml = '<div onclick="alert(\'XSS?\')">Klick mich</div>';
videoUrl = 'https://www.youtube.com/embed/dQw4w9WgXcQ';
safeHtml: SafeHtml;
safeVideoUrl: SafeResourceUrl;
constructor(private sanitizer: DomSanitizer) {
this.safeHtml = this.sanitizer.bypassSecurityTrustHtml(this.rawHtml);
this.safeVideoUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.videoUrl);
}
}Die bypassSecurityTrust*-Methoden umgehen die
Sanitization explizit. Dies sollte ausschließlich für vertrauenswürdige
Inhalte verwendet werden – niemals für Benutzereingaben ohne vorherige
Validierung. Der Methodenname ist bewusst ausführlich, um die
Ernsthaftigkeit dieser Entscheidung zu verdeutlichen.
Angular unterscheidet verschiedene Sicherheitskontexte:
bypassSecurityTrustHtml: Für HTML-InhaltebypassSecurityTrustUrl: Für Navigation-URLs in
LinksbypassSecurityTrustResourceUrl: Für Ressourcen-URLs in
iframes oder externen SkriptenbypassSecurityTrustScript: Für JavaScript-CodebypassSecurityTrustStyle: Für CSS-StylesJeder Kontext hat spezifische Sicherheitsrisiken. Ein URL-Kontext
erlaubt beispielsweise keine javascript:-URLs, während ein
Ressourcen-Kontext externe Inhalte ohne Einschränkungen lädt.
Event Binding fängt Ereignisse aus dem Template ab und leitet sie an Methoden in der Komponente. Die Syntax mit runden Klammern signalisiert diesen Datenfluss vom Template zur Komponente.
<button (click)="handleClick($event)">Klick mich</button>Angular registriert einen Event-Listener für das
click-Ereignis. Bei jedem Klick ruft das Framework die
handleClick-Methode auf und übergibt das native DOM-Event
als $event-Objekt.
Das Framework unterstützt alle nativen DOM-Ereignisse: Mausereignisse
wie click, dblclick, mousedown,
mouseup, Tastaturereignisse wie keydown,
keyup, Formulareeignisse wie submit,
change, input, focus,
blur, sowie spezialisierte Ereignisse für Drag & Drop
und Touch-Interaktionen.
<input
(input)="onInput($event)"
(focus)="highlightField(true)"
(blur)="highlightField(false)"
(keyup.enter)="submitForm()">Mehrere Event-Bindings auf einem Element sind problemlos möglich. Jedes Ereignis triggert seine eigene Handler-Methode. Die Komponente verarbeitet die Eingabe:
export class FormFieldComponent {
fieldValue = '';
isHighlighted = false;
onInput(event: Event) {
const input = event.target as HTMLInputElement;
this.fieldValue = input.value;
// Echtzeit-Validierung
if (this.fieldValue.length < 3) {
input.classList.add('invalid');
} else {
input.classList.remove('invalid');
}
}
highlightField(isActive: boolean) {
this.isHighlighted = isActive;
}
submitForm() {
console.log('Formular abgesendet mit:', this.fieldValue);
}
}Die onInput-Methode reagiert auf jede Eingabe, führt
Validierung durch und aktualisiert CSS-Klassen. Dies zeigt die
Flexibilität des Event-Systems – vom einfachen Event-Handling bis zur
komplexen Interaktionslogik.
Das $event-Objekt enthält alle Informationen über das
ausgelöste Ereignis. TypeScript bietet typisierte Event-Interfaces, die
spezifische Eigenschaften für verschiedene Event-Typen
bereitstellen.
export class EventAnalysisComponent {
handleMouseEvent(event: MouseEvent) {
console.log(`Mausposition: ${event.clientX}, ${event.clientY}`);
// Welcher Mausbutton wurde geklickt?
switch(event.button) {
case 0: console.log('Linksklick'); break;
case 1: console.log('Mittelklick/Scroll-Wheel'); break;
case 2: console.log('Rechtsklick'); break;
}
// Relative Position zum Zielelement berechnen
const target = event.target as HTMLElement;
const rect = target.getBoundingClientRect();
const relativeX = event.clientX - rect.left;
const relativeY = event.clientY - rect.top;
console.log(`Relative Position: ${relativeX}, ${relativeY}`);
// Modifier-Tasten prüfen
if (event.ctrlKey) console.log('Strg gedrückt');
if (event.shiftKey) console.log('Shift gedrückt');
if (event.altKey) console.log('Alt gedrückt');
}
handleKeyboardEvent(event: KeyboardEvent) {
console.log(`Taste: ${event.key}, Code: ${event.code}`);
// Unterschied zwischen key und code:
// key: logische Eingabe (z.B. "a" oder "A" je nach Shift)
// code: physische Taste (immer "KeyA")
if (event.code === 'KeyA' && event.key !== 'a') {
console.log('A-Taste mit alternativer Belegung');
}
}
handleTouchEvent(event: TouchEvent) {
const touches = event.touches;
console.log(`Aktive Touch-Points: ${touches.length}`);
// Multi-Touch-Gesten erkennen
if (touches.length >= 2) {
const touch1 = touches[0];
const touch2 = touches[1];
const distance = Math.sqrt(
Math.pow(touch2.clientX - touch1.clientX, 2) +
Math.pow(touch2.clientY - touch1.clientY, 2)
);
console.log(`Abstand zwischen Fingern: ${distance}px`);
}
}
}TypeScript’s Event-Typen bieten Intellisense und
Compile-Zeit-Sicherheit. Ein MouseEvent hat andere
Eigenschaften als ein KeyboardEvent oder
TouchEvent. Die IDE kann auto-complete für alle verfügbaren
Eigenschaften anbieten.
Angular bietet Syntactic Sugar für häufige Event-Kombinationen. Statt im Handler manuell zu prüfen, welche Tasten gedrückt wurden, deklariert die Template-Syntax dies direkt:
<!-- Speichern mit Strg+S -->
<textarea (keydown.control.s)="saveDocument($event)"></textarea>
<!-- Navigation mit Shift+Pfeiltasten -->
<div
(keydown.shift.arrowUp)="moveSelection('up')"
(keydown.shift.arrowDown)="moveSelection('down')"
tabindex="0">
Tastatur-navigierbarer Inhalt
</div>Die Komponente muss nicht mehr prüfen, ob Modifier-Tasten gedrückt sind:
export class DocumentEditorComponent {
saveDocument(event: KeyboardEvent) {
event.preventDefault(); // Verhindert Browser-Speicherdialog
this.documentService.save(this.currentDocument);
this.showNotification('Dokument gespeichert');
}
moveSelection(direction: 'up' | 'down') {
// Keine manuelle Prüfung von event.shiftKey nötig
console.log(`Auswahl nach ${direction} erweitern`);
}
}Verfügbare Modifikatoren umfassen Tastaturmodifikatoren
(control, shift, alt,
meta), spezifische Tasten (enter,
tab, escape, space,
backspace, delete), Pfeiltasten
(arrowUp, arrowDown, arrowLeft,
arrowRight) und Kombinationen für Mausereignisse.
Diese Modifikatoren können beliebig kombiniert werden:
(keydown.control.shift.a) fängt Strg+Shift+A ab. Die Syntax
ist deklarativ und selbstdokumentierend.
DOM-Events durchlaufen zwei Phasen: Die Capture-Phase, in der das Event vom Window zum Zielelement wandert, und die Bubbling-Phase, in der es wieder aufsteigt. Angular bindet standardmäßig an die Bubbling-Phase.
<div (click)="handleOuter($event)" class="outer">
Äußeres Element
<button (click)="handleInner($event)" class="inner">
Inneres Element
</button>
</div>Ein Klick auf den Button triggert beide Handler in dieser
Reihenfolge: erst handleInner, dann
handleOuter. Das Event “bubbelt” durch die DOM-Hierarchie
nach oben.
export class BubblingDemoComponent {
handleInner(event: Event) {
console.log('Button geklickt');
event.stopPropagation(); // Stoppt das Aufsteigen
}
handleOuter(event: Event) {
console.log('Äußeres Div geklickt');
// Wird nicht ausgeführt, wenn stopPropagation() aufgerufen wurde
}
}Die Methode stopPropagation() verhindert, dass das Event
weiter aufsteigt. Dies ist nützlich, wenn nested Elements
unterschiedliche Aktionen ausführen sollen.
Für spezielle Fälle unterstützt Angular auch Capture-Phase-Binding:
<div (click.capture)="handleCapture($event)">
Capture-Phase
<button (click)="handleBubble($event)">
Bubbling-Phase
</button>
</div>Die Capture-Phase läuft vor der Bubbling-Phase. Bei einem
Button-Klick wird zuerst handleCapture, dann
handleBubble ausgeführt. Dies ist selten nötig, kann aber
für Event-Interception oder komplexe Delegationsmuster hilfreich
sein.
Bei langen Listen kann das Hinzufügen eines Event-Handlers zu jedem Element die Performance beeinträchtigen. Event-Delegation löst dies durch einen einzelnen Handler auf einem gemeinsamen Elternelement:
<ul (click)="handleListClick($event)">
<li *ngFor="let item of items" [attr.data-id]="item.id">
{{ item.name }}
</li>
</ul>Der Handler auf dem <ul> fängt alle Klicks ab und
delegiert basierend auf dem Zielelement:
export class EfficientListComponent {
items = Array.from({length: 1000}, (_, i) => ({
id: i,
name: `Item ${i}`
}));
handleListClick(event: MouseEvent) {
let target = event.target as HTMLElement;
// Finde das nächste <li>-Element in der Hierarchie
while (target && target.tagName !== 'LI') {
target = target.parentElement as HTMLElement;
}
if (target) {
const itemId = target.getAttribute('data-id');
this.selectItem(Number(itemId));
}
}
selectItem(id: number) {
console.log(`Item ${id} ausgewählt`);
}
}Statt 1000 Event-Listener zu registrieren, genügt einer. Dies reduziert Memory-Overhead und verbessert Initial-Rendering. Die Technik funktioniert auch für dynamisch hinzugefügte Elemente, da der Handler bereits auf dem Elternelement existiert.
Two-Way Binding vereint Property Binding und Event Binding in einer
kompakten Syntax. Die Notation [()] wird oft als “Banana in
a Box” bezeichnet – die runden Klammern (Banana) stecken in den eckigen
(Box).
<input [(ngModel)]="username">Angular expandiert dies intern zu:
<input
[ngModel]="username"
(ngModelChange)="username = $event">Das Property Binding [ngModel] setzt den Input-Wert, das
Event Binding (ngModelChange) aktualisiert die
Komponenten-Eigenschaft bei Änderungen. Die Schreibweise
[(ngModel)] ist syntaktischer Zucker, der beide Mechanismen
kombiniert.
Die Verwendung erfordert den Import des FormsModule:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [
BrowserModule,
FormsModule
]
})
export class AppModule { }Ein Formular demonstriert die praktische Anwendung:
@Component({
selector: 'app-user-form',
template: `
<div class="form-group">
<label for="username">Benutzername:</label>
<input id="username" type="text" [(ngModel)]="username">
</div>
<div class="form-group">
<label for="email">E-Mail:</label>
<input id="email" type="email" [(ngModel)]="email">
</div>
<div class="preview">
<p>Benutzername: {{ username }}</p>
<p>E-Mail: {{ email }}</p>
</div>
`
})
export class UserFormComponent {
username = '';
email = '';
}Jede Änderung im Input-Feld aktualisiert sofort die Komponenten-Eigenschaft und damit die Preview. Diese bidirektionale Synchronisation eliminiert Boilerplate-Code für Formulare.
Two-Way Binding ist nicht auf ngModel beschränkt. Eigene
Komponenten können das gleiche Pattern implementieren. Die Konvention
erfordert eine Input-Eigenschaft und ein Output-Event mit dem Suffix
Change:
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-counter',
template: `
<button (click)="decrement()">-</button>
<span>{{ value }}</span>
<button (click)="increment()">+</button>
`
})
export class CounterComponent {
@Input() value: number = 0;
@Output() valueChange = new EventEmitter<number>();
increment() {
this.value++;
this.valueChange.emit(this.value);
}
decrement() {
this.value--;
this.valueChange.emit(this.value);
}
}Die Verwendung unterstützt sowohl separate Bindings als auch die Two-Way-Syntax:
<!-- Separate Bindings -->
<app-counter
[value]="count"
(valueChange)="count = $event">
</app-counter>
<!-- Two-Way Binding -->
<app-counter [(value)]="count"></app-counter>Angular erkennt das Pattern automatisch. Wenn eine Eigenschaft
foo und ein Event fooChange existieren,
funktioniert [(foo)] out-of-the-box. Diese Konvention macht
eigene Komponenten intuitiv verwendbar.
Neben dem generellen Property Binding bietet Angular spezialisierte Syntax für Attribute, CSS-Klassen und Styles. Diese Binding-Formen adressieren spezifische DOM-Aspekte, die über reguläres Property Binding umständlich wären.
HTML-Attribute ohne entsprechende DOM-Eigenschaften erfordern Attribute Binding:
<button [attr.aria-label]="description">Aktion</button>
<table [attr.role]="'grid'">...</table>
<td [attr.colspan]="columnSpan">Zelle</td>Das attr.-Präfix signalisiert Attribute-Binding. Angular
setzt das HTML-Attribut direkt, nicht eine DOM-Eigenschaft. Dies ist
essentiell für ARIA-Attribute, SVG-Eigenschaften und Custom
Data-Attributes:
<div
[attr.data-user-id]="userId"
[attr.data-role]="userRole">
Benutzer-Karte
</div>CSS-Klassen können über mehrere Wege gebunden werden:
<!-- Einzelne Klasse toggeln -->
<div [class.active]="isActive">Status</div>
<!-- Mehrere Klassen als String -->
<div [class]="'btn btn-primary'">Button</div>
<!-- Klassen-Objekt -->
<div [class]="classObject">Multi-Class</div>Die Komponente definiert das Klassen-Objekt:
export class StyleComponent {
isActive = true;
classObject = {
'active': this.isActive,
'highlighted': true,
'disabled': false
};
}Angular wendet nur die Klassen an, deren Wert true ist.
Diese Syntax ist prägnanter als String-Konkatenation, besonders bei
vielen bedingten Klassen.
Inline-Styles werden ähnlich gebunden:
<!-- Einzelner Style -->
<div [style.color]="textColor">Text</div>
<!-- Mit Einheit -->
<div [style.width.px]="elementWidth">Element</div>
<!-- Style-Objekt -->
<div [style]="styleObject">Styled</div>Die Komponente:
export class StyleComponent {
textColor = '#ff0000';
elementWidth = 200;
styleObject = {
'color': this.textColor,
'font-size': '16px',
'font-weight': 'bold'
};
}Das .px-Suffix fügt automatisch die Einheit hinzu.
Angular unterstützt auch andere Einheiten wie .em,
.%, .rem. Dies eliminiert String-Konkatenation
für Style-Werte mit Einheiten.
Property und Event Binding funktioniert nicht nur mit DOM-Elementen, sondern auch mit Direktiven. Angular’s eingebaute Direktiven nutzen dies extensiv:
<div *ngIf="isVisible">Sichtbarer Inhalt</div>
<div *ngFor="let item of items">{{ item }}</div>
<div [ngClass]="classExpression">Dynamische Klassen</div>
<div [ngStyle]="styleExpression">Dynamische Styles</div>Eigene Direktiven können ebenfalls Input-Properties definieren:
import { Directive, Input, ElementRef, OnInit } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective implements OnInit {
@Input() appHighlight: string;
@Input() defaultColor = 'yellow';
constructor(private el: ElementRef) {}
ngOnInit() {
const color = this.appHighlight || this.defaultColor;
this.el.nativeElement.style.backgroundColor = color;
}
}Die Verwendung im Template:
<p appHighlight="lightblue">Blau hervorgehobener Text</p>
<p [appHighlight]="highlightColor">Dynamisch hervorgehobener Text</p>Direktiven erweitern DOM-Elemente um zusätzliches Verhalten, ohne neue Komponenten zu erstellen. Property Binding macht sie konfigurierbar, Event Binding ermöglicht Kommunikation zurück zur Komponente.
Die Kombination aus Komponenten, Direktiven und den verschiedenen Binding-Mechanismen bildet das Fundament für Angular’s deklaratives, kompositionsfähiges UI-Modell. Binding abstrahiert die imperative DOM-Manipulation und erlaubt es Entwicklern, sich auf die Geschäftslogik zu konzentrieren statt auf technische Details der Browser-APIs.