Directive sind neben Komponenten eines der zentralen Konzepte in Angular. Anders als Components bringt eine Directive kein eigenes Template mit, sondern erweitert die eigene Anwendung um Funktionalität.
Bevor wir zum eigentlich Hostbinding kommen, werfen wir noch mal einen Blick auf die Grundlagen einer Direktive:
Verwendung:
<div gedLoremIpsumContent>
Implementierung:
@Directive({ selector: '[gedLoremIpsumContent]', }) export class LoremIpsumContentDirective {}
Syntaktisch unterscheidet sich eine Direktive kaum von einer Component, analog müssen wir auch hier einen Selektor verwenden mit dessen Hilfe wir unsere Directive später im Template vewenden können. In diesem Fall haben wir uns für einen Attributs-Selector entschieden. Alternativ hätten wir hier auch auf einen Tag-Selector (“gedLoremIpsumContent”) oder einen CSS-Selector (“.gedLoremIpsumContent”) setzen können.
Das oben gezeigte Beispiel funktioniert, ohne sichtbaren nutzen, tadellos und erzeugt für das DIV das unsere Directive verwendet auch eine entsprechende Objektinstanz. Innerhalb unserer Direktive können wir nun Einfluss auf das DOM-Element nehmen auf dem unsere Direktive verwendet wird (der so genannten “Host”). Hierzu stehen uns 4 Möglichkeiten zur Verfügung.
ElementRef
Die Klasse “ElementRef” bietet uns eine entsprechende Schnittstelle an um auf das zugrunde liegende HTML-Element zugreifen zu können. Nach der Injektion über den Konstruktor liefert die so erhaltene Instanz mittels der Methode “nativeElement” den Zugriff auf die DOM-API. Hierüber sind wir nun in der Lage die gewünschten Manipulationen am Element vorzunehmen.
constructor(element: ElementRef) { element.nativeElement.style.cursor = 'pointer'; }
Der direkte Zugriff auf die DOM API sollte jedoch nur im äußersten Notfall verwendet werden. Angular ist so konzipiert das der Browser nur eines der möglichen Anzeige-Medien ist. Hier sind auch native Clients, mobile Geräte und serverseitiges Rendering möglich, die keinen zugrundeliegenden DOM-Baum haben und auch lässt sich eine Direktive die sich direkt auf das native Element stützt nicht per Unit-Tests testen.
Renderer
Der Renderer ist im Grunde eine Abstraktion für den direkten Zugriff auf die DOM-API und sollte immer vorrangig, vor der direkten Verwendung des “nativeElement” , verwendet werden. Diese Klasse bietet diverse Methoden an um das zugrunde liegende DOM-Element zu manipulieren.
constructor(element: ElementRef, renderer:Renderer2) { renderer.setStyle(element.nativeElement, "border", "1px solid black"); }
HostBinding
Das HostBinding bietet uns die Möglichkeit das Attribut von unserem Host (in diesem Beispiel dem DIV-Element) direkt an eine eine Property zu binden, ohne das wir uns im weiteren Programm-Verlaufen darum kümmern müssen das Änderungen des Wertes auch am DOM-Elemente aktualisiert werden.
@HostBinding('innerHTML') innerHTML: string; ngOnChanges() { this.innerHTML = 'Hello World'; }
Alternativ zur (empfohlenen) Verwendung des @HostBinding Decorators kann das Binding auch bei der Deklaration der Directive gesetzt werden:
@Directive({ selector: '[gedLoremIpsumContent]', exportAs: 'loremIpsumContent', host: { 'class': 'demo', '(mouseenter)': 'mouseEnter()' } })
HostListener
HostListener bieten uns analog zum HostBinding Zugriff auf Events die auf dem Host auftreten können. Dazu verwendenden wir den @HostListener-Decorator an eine unserer Methoden und legen fest welches Event verarbeitet werden und welche Parameter übergeben werden sollen
@HostListener('click', ['$event']) onHostClick($event) { this.innerHTML="New Value"; }
Mit diesen Möglichkeiten bietet Angular alles um sicher und einfach direkt oder indirekt mit den Elementen des DOM-Baumes zu arbeiten. Das Ganze als Live-Beispiel gibt es wie immer in