@HostBinding und @HostListener: Was machen sie und wofür sind sie?


188

In meinen Windungen im weltweiten Interweb und jetzt besonders in den Dokumenten im Angular.io-Stil finde ich viele Verweise auf @HostBindingund @HostListener. Es scheint, dass sie ziemlich grundlegend sind, aber leider ist die Dokumentation für sie im Moment ein wenig lückenhaft.

Kann jemand bitte erklären, was sie sind, wie sie funktionieren und ein Beispiel für ihre Verwendung geben?

Antworten:


139

Haben Sie diese offiziellen Dokumente überprüft?

HostListener - Deklariert einen Host-Listener. Angular ruft die dekorierte Methode auf, wenn das Host-Element das angegebene Ereignis ausgibt.

@HostListener- hört das Ereignis ab, das von dem Host-Element ausgegeben wird, mit dem deklariert wurde @HostListener.

HostBinding - Deklariert eine Bindung der Host-Eigenschaft. Angular überprüft die Host-Eigenschaftsbindungen während der Änderungserkennung automatisch. Wenn sich eine Bindung ändert, wird das Host-Element der Direktive aktualisiert.

@HostBinding- bindet die Eigenschaft an das Host-Element. Wenn sich eine Bindung ändert, HostBindingwird das Host-Element aktualisiert.


HINWEIS: Beide Links wurden kürzlich entfernt. Der Abschnitt " HostBinding-HostListening " des Styleguides kann eine nützliche Alternative sein, bis die Links zurückkehren.


Hier ist ein einfaches Codebeispiel, um sich ein Bild davon zu machen, was dies bedeutet:

DEMO: Hier ist die Demo live im Plunker - "Ein einfaches Beispiel für @HostListener & @HostBinding"

  • In diesem Beispiel wird eine rolemit deklarierte Eigenschaft @HostBindingan das Element des Hosts gebunden
    • Denken Sie daran, dass dies roleein Attribut ist, da wir es verwenden attr.role.
    • <p myDir>wird, <p mydir="" role="admin">wenn Sie es in Entwicklertools anzeigen.
  • Anschließend wird das onClickmit dem @HostListenerHostelement der Komponente angehängte Ereignis abgehört, das rolemit jedem Klick geändert wird.
    • Die Änderung beim <p myDir>Klicken auf besteht darin, dass sich das öffnende Tag von <p mydir="" role="admin">nach <p mydir="" role="guest">und zurück ändert .

directives.ts

import {Component,HostListener,Directive,HostBinding,Input} from '@angular/core';

@Directive({selector: '[myDir]'})
export class HostDirective {
  @HostBinding('attr.role') role = 'admin'; 
  @HostListener('click') onClick() {
    this.role= this.role === 'admin' ? 'guest' : 'admin';
  }
}

AppComponent.ts

import { Component,ElementRef,ViewChild } from '@angular/core';
import {HostDirective} from './directives';

@Component({
selector: 'my-app',
template:
  `
  <p myDir>Host Element 
    <br><br>

    We have a (HostListener) listening to this host's <b>click event</b> declared with @HostListener

    <br><br>

    And we have a (HostBinding) binding <b>the role property</b> to host element declared with @HostBinding 
    and checking host's property binding updates.

    If any property change is found I will update it.
  </p>

  <div>View this change in the DOM of the host element by opening developer tools,
    clicking the host element in the UI. 

    The role attribute's changes will be visible in the DOM.</div> 
    `,
  directives: [HostDirective]
})
export class AppComponent {}

1
Wird dieser Dekorateur noch verwendet, scheinen die Links aus der Angular2-Dokumentation entfernt worden zu sein
CommonSenseCode

1
Ja, es wird noch verwendet, aber ich möchte es einmal bestätigen. Ich werde Sie aktualisieren, wenn ich etwas anderes herausfinden kann.
Mikronyken


1
@ Mr.EasyAnswersMcFly aktualisierte Antwort mit Hinweis und Link. Bitte beachten Sie, dass noch keine ordnungsgemäße Dokumentation verfügbar ist.
Mikronyken

1
@ MuhammadSaleh für Scroll es ist schwer zu sagen, wie es zählt und berechnet ... aber das ist sicher, dass jede Instanz einen separaten Listener haben wird
Mikronyken

112

Ein kurzer Tipp, der mir hilft, mich daran zu erinnern, was sie tun -

HostBinding('value') myValue; ist genau das gleiche wie [value]="myValue"

Und

HostListener('click') myClick(){ } ist genau das gleiche wie (click)="myClick()"


HostBindingund HostListenersind in den Richtlinien und den anderen geschrieben (...)und [..]sind innerhalb Vorlagen geschrieben (von Komponenten).


9
Ah, dank dieser Antwort hat es bei mir geklickt (Wortspiel beabsichtigt). @HostListenerDies ist der richtige Weg, wenn Sie im DOM nichts für eine typische Ereignisbindung haben, wie z. B. Tastatureingaben in meinem Fall.
MrBoJangles

46

Hier ist ein einfaches Schwebebeispiel.

Vorlageneigenschaft der Komponente:

Vorlage

<!-- attention, we have the c_highlight class -->
<!-- c_highlight is the selector property value of the directive -->

<p class="c_highlight">
    Some text.
</p>

Und unsere Richtlinie

import {Component,HostListener,Directive,HostBinding} from '@angular/core';

@Directive({
    // this directive will work only if the DOM el has the c_highlight class
    selector: '.c_highlight'
 })
export class HostDirective {

  // we could pass lots of thing to the HostBinding function. 
  // like class.valid or attr.required etc.

  @HostBinding('style.backgroundColor') c_colorrr = "red"; 

  @HostListener('mouseenter') c_onEnterrr() {
   this.c_colorrr= "blue" ;
  }

  @HostListener('mouseleave') c_onLeaveee() {
   this.c_colorrr = "yellow" ;
  } 
}

28
Ich sehe diese akzeptierte Antwort nicht als Antwort auf die gestellte Frage. Möchten Sie eine Erklärung geben? Wie machen c_colorrr, c_onEnterrr (), c_onLeaveeee in diesem bestimmten Code-Snippet?
Luqo33

1
Ich denke, es sollte die Farbe ändern, wenn die Maus das Ereignis in Blau eingibt und wenn die Maus das Ereignis in Gelb verlässt.
Michał Ziobro

Wo platzieren Sie die Direktive im Markup? Scheint, Sie würden es auf dem Body-Tag platzieren, aber das wäre außerhalb der Root-Komponente. Wenn Sie durch diese Antwort verwirrt sind, könnte dieser Link ng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding
mtpultz

@mtpultz Es ist in der Klasse.
Serkan

33

Eine weitere nette Sache @HostBindingist, dass Sie es kombinieren können, @Inputwenn Ihre Bindung direkt auf einer Eingabe beruht, z.

@HostBinding('class.fixed-thing')
@Input()
fixed: boolean;

1
Können Sie bitte ein Beispiel für die Verwendung mit teilen @Input()?
Mano

Das Beispiel ist genau dort in meiner Antwort, Sie schreiben einfach beide Dekorateure nacheinander, Reihenfolge sollte irrelevant sein
altschuler

1
Ich denke, was mir fehlt, ist, wie sich dies von der bloßen Verwendung unterscheidet @HostBinding. Wann müssen Sie verwenden @Input?
1252748

11

Eine Sache, die dieses Thema verwirrt, ist die Idee der Dekorateure, die nicht sehr klar gemacht wird, und wenn wir so etwas wie ...

@HostBinding('attr.something') 
get something() { 
    return this.somethingElse; 
 }

Es funktioniert, weil es ein getAccessor ist . Sie konnten kein Funktionsäquivalent verwenden:

@HostBinding('attr.something') 
something() { 
    return this.somethingElse; 
 }

Andernfalls besteht der Vorteil der Verwendung @HostBindingdarin, dass sichergestellt wird, dass die Änderungserkennung ausgeführt wird, wenn sich der gebundene Wert ändert.


8

Zusammenfassung:

  • @HostBinding: Dieser Dekorator bindet eine Klasseneigenschaft an eine Eigenschaft des Hostelements.
  • @HostListener: Dieser Dekorator bindet eine Klassenmethode an ein Ereignis des Hostelements.

Beispiel:

import { Component, HostListener, HostBinding } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `<p>This is nice text<p>`,
})
export class AppComponent  {

  @HostBinding('style.color') color; 

  @HostListener('click')
  onclick() {
    this.color =  'blue';
  }

}

Im obigen Beispiel tritt Folgendes auf:

  • Dem Klickereignis wird ein Ereignis-Listener hinzugefügt, der ausgelöst wird, wenn irgendwo innerhalb der Komponente ein Klickereignis auftritt
  • Die colorEigenschaft in unserer AppComponentKlasse ist an die style.colorEigenschaft der Komponente gebunden . Wenn also die colorEigenschaft aktualisiert wird, wird dies auch der Fall seinstyle.color Eigenschaft unserer Komponente
  • Das Ergebnis ist, dass die Farbe jedes Mal aktualisiert wird, wenn jemand auf die Komponente klickt.

Verwendung in @Directive:

Obwohl es für Komponenten verwendet werden kann, werden diese Dekoratoren häufig in Attributanweisungen verwendet. Bei Verwendung in einem @Directiveändert der Host das Element, auf dem die Direktive platziert ist. Schauen Sie sich zum Beispiel diese Komponentenvorlage an:

<p p_Dir>some paragraph</p>

Hier ist p_Dir eine Direktive für das <p>Element. Wenn @HostBindingoder @HostListenerinnerhalb der Direktivenklasse verwendet wird, verweist der Host jetzt auf die <p>.


6

Theorie mit weniger Jargons

@Hostlistnening befasst sich im Wesentlichen mit dem Host-Element say (einer Schaltfläche), das eine Aktion eines Benutzers abhört und eine bestimmte Funktion "say alert" ("Ahoi!") Ausführt, während @Hostbinding umgekehrt ist. Hier hören wir uns die Änderungen an, die intern an dieser Schaltfläche vorgenommen wurden (sagen wir, als darauf geklickt wurde, was mit der Klasse passiert ist), und verwenden diese Änderung, um etwas anderes zu tun, z. B. eine bestimmte Farbe zu emittieren.

Beispiel

Stellen Sie sich das Szenario vor, in dem Sie ein Lieblingssymbol für eine Komponente erstellen möchten. Jetzt wissen Sie, dass Sie wissen müssen, ob das Element mit geänderter Klasse favorisiert wurde. Wir benötigen eine Möglichkeit, dies zu bestimmen. Genau hier kommt @Hostbinding ins Spiel.

Und wo es notwendig ist zu wissen, welche Aktion tatsächlich vom Benutzer ausgeführt wurde, kommt @Hostlistening ins Spiel


3
Dies ist verwirrend und die Namen der Dekorateure sind ungenau.
Matmancini
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.