navigation Navigation


Host Elements


In Angular ist das Host Element das DOM-Element, an das eine Komponente gebunden ist. Wenn man eine Komponente wie app-button im Template verwendet, wird dieses Element zum Host Element der Button-Komponente. Dieses Host Element ist eine Brücke zwischen der Komponente und dem DOM und bietet viele Möglichkeiten zur Interaktion und Manipulation.

Zugriff über ElementRef

Angular erstellt für jede Komponente ein entsprechende DOM-Element, auf das man zugreifen kann.

Wenn man eine Komponente mit einem Component Selector definiert, wird ein DOM-Element mit dem Namen des Selektors erstellt.

access-elementref.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'app-access-elementref',
    imports: [],
    templateUrl: './access-elementref.component.html',
    styleUrl: './access-elementref.component.scss'
})
export class AccessElementrefComponent {}

Dieser obere Code erzeugt ein DOM-Element <app-access-elementref>, wie man es auf dem folgenden Screenshot sehen kann.

Angular erstellt ein DOM-Element für ein Component

Würde man ein Component mit einem CSS-Selektor definieren, wie beispielsweise .access-elementref, kann man <app-access-elementref> zur Verwendung/Einbindung eines Components nicht mehr verwenden. In diesem Fall würde Angular mitteilen, dass dieses Element nicht bekannt ist.

access-elementref.component.ts
import { Component } from '@angular/core';

@Component({
    selector: '.access-elementref',
    imports: [],
    templateUrl: './access-elementref.component.html',
    styleUrl: './access-elementref.component.scss'
})
export class AccessElementrefComponent {}

Angular Component CSS Selektor mit Element Selektor

Angular Component CSS Selektor mit Element Selektor - Fehler

In diesem Fall müsste man dann entsprechend auch die Verwendung des Components anpassen und über eine CSS-Klasse realisieren.

other.component.html
<div class="access-elementref"></div>

Mit dieser Verwendung, würde wieder alles korrekt fuktionienren.

Angular Component CSS Selektor korrekte Verwendung

Mit Hilfe unterschiedlicher Selektoren hat man am Ende immer ein Element im DOM, das dem entsprechenden Component zugeordnet ist bzw. das dieses Component darstellt/repräsentiert.

Das wir nun wissen, dass es immer ein entsprechendes DOM-Element zu einem Component gibt, können wir auf unterschiedliche Weisen Zugriff auf dieses Element erlangen. Zunächst wird eine Möglichkeit des Zugriffs über ElementRef gezeigt.

Wir definieren ein Component und binden ElementRef ein und weisen es eine Variable zu, über die wir dann auf die Eigenschaft nativeElement zugreifen werden.

access-elementref.component.ts
import { Component, ElementRef } from '@angular/core';

@Component({
    selector: 'app-access-elementref',
    imports: [],
    templateUrl: './access-elementref.component.html',
    styleUrl: './access-elementref.component.scss'
})
export class AccessElementrefComponent {
    constructor(
        private elementRef: ElementRef
    ) {
        const componentElement = this.elementRef.nativeElement;
        console.log('Aktuelles Element', componentElement);
    }
}

Irgendwo an einer anderen Stelle in der Applikation wird dieses Component verwendet/eingebunden. Bei der aktuellen Definition gibt eine Standardausgabe access-elementref works!. Viel interessanter ist der Inhalt der Konsole in Developer Tools.

Hier haben wir folgende Ausgabe.

Angular Component ElementRef Zugriff auf das Element

Diese Methode bietet einen direkten Zugriff auf das native DOM-Element, sollte aber mit Vorsicht verwendet werden, da der direkte DOM-Zugriff die Plattformunabhängigkeit von Angular einschränken kann und bestimmte Sicherheitsrisiken öffnet.

Zugriff mit Renderer2

Diese Methode eignet sich für eine sichere und plattformunabhängige Interatkion mit dem Host Element.

In diesem Element wird ebenfalls ElementRef verwendet. Allerdings nicht, um direkt auf das DOM-Element, sondern um das Host-Element zuzugreifen.

access-renderer.component.ts
import { Component, ElementRef, Renderer2 } from '@angular/core';

@Component({
    selector: 'app-access-renderer',
    imports: [],
    template: `<p>Component mit Renderer2</p>`,
    styleUrl: './access-renderer.component.scss'
})
export class AccessRendererComponent {

    constructor(
        private elementRef: ElementRef,
        private renderer: Renderer2
    ) {

        this.renderer.setAttribute(
            this.elementRef.nativeElement,
            'title',
            'Beispiel Tooltip'
        );

    }

}

Mit dem Renderer2 kann man verschiedene Dinge tun. In diesem Beispiel fügen dem Host-Element, also dem Component-Element das Attribute title mit dem Wert Beispiel Tooltip hinzu.

Angular Component Renderer2 - Manipulation


Event gesteuerte Aktionen

Man hat auch die Möglichkeit erst bei einem Event etwas mit dem Renderer2 zu tun. Im nächsten Beispiel wird das Beispiel von oben erweitert und ein Button hinzugefügt. Der Klick auf diesen Button führt die Funktion addClass() aus, welcher den Renderer2 verwendet, um unserem Host Element eine Klasse hinzuzufügen.

access-renderer.component.ts
import { Component, ElementRef, Renderer2 } from '@angular/core';

@Component({
    selector: 'app-access-renderer',
    imports: [],
    template: `
        <p>Component mit Renderer2</p>
        <button (click)="addClass()">
            Add class
        </button>
    `,
    styleUrl: './access-renderer.component.scss'
})
export class AccessRendererComponent {

    constructor(
        private elementRef: ElementRef,
        private renderer: Renderer2
    ) {

        this.renderer.setAttribute(
            this.elementRef.nativeElement,
            'title',
            'Beispiel Tooltip'
        );

    }

    addClass(): void {
        this.renderer.addClass(
            this.elementRef.nativeElement,
            'new-class'
        );
    }

}

Angular Component Renderer2 - Event based

Host Bindings - Attribute & Eigenschaften

Mit @HostBinding kann man Eigenschaften des Host Elements (Component Elements) an Eigenschaften (der aktuellen Component-Klasse) binden.

Das folgende Beispiel zeigt eine der einfachsten Verwendungsmöglichkeiten. In diesem Beispiel setzen wir einfach die Hintergrundfarbe für das Component mit HostBinding auf einen bestimmten Wert.

access-renderer.component.ts
import { Component, HostBinding } from '@angular/core';

@Component({
    selector: 'app-hostbinding-props',
    imports: [],
    template: `
        <p>Ein Platzhalter-Text</p>
    `,
    styleUrl: './hostbinding-props.component.scss'
})
export class HostbindingPropsComponent {

    @HostBinding('style.backgroundColor') styleBgColor = 'lightblue';

}

Wenn wir es bei dieser Konfiguration belassen, wird dieses style Attribut tatsächlich dem Host Element (Component Element) hinzufügen, hat allerdings keine Auswirkung.

So würde das Ergebnis im Browser aussehen.

Angular Host Binding - Keine Auswirkung der Stile

GRUND

Ein Host Element in Angular benötigt eine Größen oder Display-Angabe, damit die Stille auch wirklich anwendet.

Wir erweitern unser Beispiel und ergänzen die Stile. Das tun wir ebenfalls mit @HostBinding und fügen diesmal eine Klasse hinzu.

access-renderer.component.ts
import { Component, HostBinding } from '@angular/core';

@Component({
    selector: 'app-hostbinding-props',
    imports: [],
    template: `
        <p>Ein Platzhalter-Text</p>
    `,
    styleUrl: './hostbinding-props.component.scss'
})
export class HostbindingPropsComponent {

    @HostBinding('style.backgroundColor') styleBgColor = 'lightblue';
    @HostBinding('style.display') styleDisplay = 'block';

}

Jetzt wird unsere Hintergrundfarbe korrekt auf das Host Element angewendet.

Angular Host Binding - Korrekte Anwendung der Stile

Mit diesem Beispiel wurde gezeigt, dass man u.a. Stile auf ein Host Element mit Hilfe von @HostBinding anwenden kann.

Was noch gar keine Verwendung hatte, sind die zugewiesenen Variablen wie styleBgColor und styleDisplay. Diese Zuweisung wird erst interessant, wenn man diese Variablen für das Ändern der Werte verwendet.

Im nächsten Beispiel wird unserem Component ein Button hinzugefügt, welcher bei Klick eine Funktion aufruft, die, ebenfalls mittels @HostBinding bzw. der bereits vorhandenen Variable styleBgColor den Wert der Hintergrundfarbe auf transparent ändert.

access-renderer.component.ts
import { Component, HostBinding } from '@angular/core';

@Component({
    selector: 'app-hostbinding-props',
    imports: [],
    template: `
        <p>Ein Platzhalter-Text</p>
        <button (click)="changeBg()">
            Hintergrund ändern
        </button>
    `,
    styleUrl: './hostbinding-props.component.scss'
})
export class HostbindingPropsComponent {

    @HostBinding('style.backgroundColor') styleBgColor = 'lightblue';
    @HostBinding('style.display') styleDisplay = 'block';

    changeBg(): void {
        this.styleBgColor = 'transparent';
    }

}

Sobald man nun auf den Button klickt, wird der Hintergrund unseren gesamten Host Elements (Components) von lightblue auf transparent geändert.

Angular Host Binding - Event-basierte Verwendung von Variablen

Wichtiger Hinweis

In diesen Beispielen wurde eine Bindung an ein Attribut ausgeführt. Das erkennt man an dem Punkt ., welcher den das Attribut und den Wert verbindet.

In diesem Fall: style ist das Attribut und backgroundColor ist der Name der Attributs-Eigenschaft.

Auf Events reagieren

Mit @HostBinding kann man auf verschiedene Events reagieren und diese an bestimmte Funktionen binden, um einen Code-Abschnitt auszuführen.

Im folgenden Beispiel wird ein einfaches Klick-Event auf das Host Element (Component) gelegt und bei jedem Klick die Variable counter um 1 erhöht.

Damit man die Fläche des Components (Host Elements) besser sieht, wurden ein paar CSS-Stile, ebenfalls per @HostBinding, hinzugefügt. Diese könnte man auch über die dazugehörige SCSS-Datei hinzufügen können.

counter.component.ts
import { Component, HostBinding, HostListener } from '@angular/core';

@Component({
    selector: 'app-hostbinding-dynamic',
    imports: [],
    template: `
        <div>Counter: {{ counter }}</div>
    `,
    styleUrl: './hostbinding-dynamic.component.scss'
})
export class HostbindingDynamicComponent {

    counter = 0;

    @HostBinding('style.padding') componentPadding = '20px';
    @HostBinding('style.boxSizing') componentBoxSizing = 'border-box';
    @HostBinding('style.backgroundColor') componentBgColor = 'lightblue';
    @HostBinding('style.display') componentDisplay = 'block';

    @HostListener('click')
    onClick(): void {
        this.counter++;
    }

}

Angular Host Binding - Klick Event

@HostListener für Events

Während man mit @HostBinding Eigenschaften und Attribute an Eigenschaften und Methoden des Components binden kann, kann man mit @HostListener verschiedene Event-Listener an das Component Element (Host Element) binden.

Das folgende Beispiel zeit eine einfach Implementierung eines Maus-Trackers, welche die Werte nur dann aktualisiert, wenn die Maus sich über der Fläche des Components bewegt. Dies ist der Fall, weil (in diesem Fall) nur dort ein Event-Listener dafür registriert wurde.

Damit man eine visuelle Fläche hat, wurden ein paar Stile hinzufügt. Diesmal in der SCSS-Datei.

mousetracker.component.scss
:host {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    width: 600px;
    height: 400px;
    background-color: lightblue;
}

In unserer Component-Klasse wird nun @HostListener verwendet. Wir binden das Event mousemove an unser Component.

mousetracker.component.ts
import { Component, HostListener } from '@angular/core';

@Component({
    selector: 'app-hostbinding-mousetracker',
    imports: [],
    templateUrl: './hostbinding-mousetracker.component.html',
    styleUrl: './hostbinding-mousetracker.component.scss'
})
export class HostbindingMousetrackerComponent {

    x = 0;
    y = 0;

    @HostListener('mousemove', ['$event'])
    onMouseMove(event: MouseEvent): void {
        this.x = event.clientX;
        this.y = event.clientY;
    }

}

Angular Host Binding - Host Listener Beispiel


Globale Events mit @HostListener

Man hat auch die Möglichkeit globale Events mit @HostListener zu definieren auf diese entsprechend zu reagieren.

Im nächsten Beispiel wird ein Component definiert, welches die zuletzt gedrückte Taste ausgibt.

mousetracker.component.ts
import { Component, HostListener } from '@angular/core';

@Component({
    selector: 'app-hostbinding-globalevents',
    imports: [],
    template: `
        <p>Letzte Taste: {{ lastPressedKey }}
    `,
    styleUrl: './hostbinding-globalevents.component.scss'
})
export class HostbindingGlobaleventsComponent {

    lastPressedKey = '';

    @HostListener('window:keydown', ['$event'])
    onKeyDown(event: KeyboardEvent): void {
        if (event.code === 'Space') {
            this.lastPressedKey = 'Leertaste';
        } else {
            this.lastPressedKey = event.key;
        }
    }

}

Angular Host Binding - Host Listener - Globale Events

Verwendung der host Eigenschaft

Kann alternativ auch die host Eigenschaft im Component Dekorator verwenden, um Stile, Attribute oder Events einem Host Element (Component) hinzuzufügen.

mousetracker.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'app-host-property',
    standalone: true,
    template: `<p>host Eigenschaft</p>`,
    host: {
        'class': 'custom_class',
        '[class.active]': 'isActive',
        '(click)': 'onClick()',
        '[attr.title]': '"My Custom title"',
        '[style.display]': '"block"',
        '[style.backgroundColor]': '"lightblue"'
    }
})
export class HostPropertyComponent {

    isActive = true;

    onClick(): void {
        console.log('Click on component done');
    }

}

Als Ergebnis hat man ein Component, ausgestattet mit Attributen, Stilen und Event-Listenern, wie wenn man @HostBinding und @HostListener innerhalb der Component-Klasse verwenden würde.

Angular Host Binding - host Eigenschaft (1)

Angular Host Binding - host Eigenschaft (2)