Jede Angular-Komponente wird in ein HTML-Element im DOM gerendert – dieses Element nennt man das Host-Element (z. B. <app-button>). Während du im Template der Komponente vollen Zugriff auf das Innere der Komponente hast, musst du spezielle Techniken anwenden, um Attribute, Klassen oder Events direkt auf dem Host-Element selbst zu setzen. Dieser Artikel zeigt dir die modernen und klassischen Methoden dafür.

Binding mit der host Eigenschaft (Modern)

Der von Angular empfohlene Weg, um mit dem Host-Element zu interagieren, ist die host-Eigenschaft innerhalb des @Component-Dekorators. Sie bündelt alle Host-Bindings übersichtlich an einem Ort.

Du kannst dort statische Attribute, dynamische Bindings (wie Klassen oder Styles) und Event-Listener definieren.

TypeScript custom-slider.component.ts
import { Component, signal } from '@angular/core';

@Component({
    selector: 'app-custom-slider',
    template: `<div>Slider Inhalt</div>`,
    host: {
        // Statisches Attribut (wird immer so gerendert: role="slider")
        'role': 'slider',

        // Dynamisches Klassen-Binding (Klasse 'active' wird gesetzt, wenn isActive() true ist)
        '[class.active]': 'isActive()',

        // Dynamisches Style-Binding
        '[style.background]': `hasError() ? 'red' : 'green'`,

        // Attribut-Binding
        '[attr.aria-valuenow]': 'value',

        // Event-Listener (lauscht auf Tastatur-Events auf dem Host-Tag)
        '(keydown)': 'updateValue($event)'
    },
    standalone: true
})
export class CustomSliderComponent {
    value: number = 0;
    isActive = signal(false);
    hasError = signal(false);

    updateValue(event: KeyboardEvent) {
        // Event verarbeiten
    }
}

Globale Event-Listener

Du kannst über die host-Eigenschaft auch auf globale Events wie das window oder document lauschen:

TypeScript host-global.ts
host: {
    // Lauscht auf Scroll-Events des gesamten Fensters
    '(window:scroll)': 'onWindowScroll($event)',
    // Lauscht auf Klicks irgendwo im Dokument
    '(document:click)': 'onDocumentClick($event)'
}

@HostBinding und @HostListener (Klassisch)

In vielen bestehenden Projekten findest du stattdessen die Dekoratoren @HostBinding und @HostListener. Sie funktionieren exakt genauso wie die host-Eigenschaft, verteilen die Logik aber über die gesamte TypeScript-Klasse.

TypeScript legacy-host.ts
import { Component, HostBinding, HostListener } from '@angular/core';

@Component({
    selector: 'app-legacy-slider',
    template: `...`
})
export class LegacySliderComponent {
    // Bindet die Eigenschaft "value" an das aria-valuenow Attribut des Hosts
    @HostBinding('attr.aria-valuenow') value: number = 0;

    // Dynamisches Setzen des tabIndex
    @HostBinding('tabIndex') get tabIndex() {
        return this.isDisabled ? -1 : 0;
    }
    isDisabled = false;

    // Lauscht auf keydown Events des Hosts
    @HostListener('keydown', ['$event'])
    updateValue(event: KeyboardEvent) {
        // ...
    }
}

Kollisionen: Wer gewinnt?

Es kann vorkommen, dass eine Komponente ein Host-Binding definiert, der Entwickler aber beim Verwenden der Komponente dasselbe Attribut nochmals von außen setzt.

Beispiel – Die Komponente definiert intern:

host: { 'role': 'presentation', '[id]': 'id' }

Und wird im HTML so aufgerufen:

<app-photo role="group" [id]="otherId" />

Die Regeln zur Konfliktauflösung lauten:

  1. Wenn beide Werte statisch sind (role="presentation" intern vs. role="group" extern), gewinnt der äußere (externe) Wert.
  2. Wenn ein Wert statisch und der andere dynamisch ist, gewinnt der dynamische Wert.
  3. Wenn beide Werte dynamisch sind, gewinnt das interne Host-Binding der Komponente.

Statische Attribute auslesen (HostAttributeToken)

Wenn du in deiner Komponente ein statisches HTML-Attribut (kein Input-Binding!) auslesen möchtest, das der Host-Komponente übergeben wurde, kannst du das HostAttributeToken zusammen mit inject() verwenden.

Das ist sehr performant, da Angular hierfür keinen Change-Detection-Zyklus benötigt.

TypeScript host-attribute.ts
import { Component, HostAttributeToken, inject } from '@angular/core';

@Component({
    selector: 'app-button',
    template: `<button>Klick mich</button>`,
    standalone: true
})
export class ButtonComponent {
    // Liest das statische Attribut "variation" aus (z.B. <app-button variation="primary">)
    // Wirft einen Fehler, wenn das Attribut fehlt!
    variation = inject(new HostAttributeToken('variation'));
    
    // Mit optionalem Fallback:
    // variation = inject(new HostAttributeToken('variation'), { optional: true }) ?? 'default';
}

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Komponenten-Interaktion

Zur Übersicht