@HostBinding i @HostListener: co robią i do czego służą?


191

W moich wędrówkach po całym świecie, a teraz zwłaszcza w dokumentach w stylu angular.io , znajduję wiele odniesień do @HostBindingi @HostListener. Wydaje się, że są one dość fundamentalne, ale niestety dokumentacja do nich w tej chwili jest trochę szkicowa.

Czy ktoś może wyjaśnić, czym one są, jak działają i podać przykład ich użycia?

Odpowiedzi:


141

Sprawdziłeś te oficjalne dokumenty?

HostListener - deklaruje odbiornik hosta. Angular wywoła dekorowaną metodę, gdy element hosta wyemituje określone zdarzenie.

@HostListener- nasłuchuje zdarzenia emitowanego przez element hosta zadeklarowany za pomocą @HostListener.

HostBinding - deklaruje powiązanie właściwości hosta. Angular automatycznie sprawdza powiązania właściwości hosta podczas wykrywania zmian. Jeśli powiązanie ulegnie zmianie, zaktualizuje element hosta dyrektywy.

@HostBinding- powiąże właściwość z elementem hosta, jeśli powiązanie ulegnie zmianie, HostBindingzaktualizuje element hosta.


UWAGA: Oba łącza zostały niedawno usunięte. Część przewodnika stylówHostBinding-HostListening ” może być użyteczną alternatywą do czasu powrotu linków.


Oto prosty przykład kodu, który pomaga zobrazować, co to oznacza:

DEMO: Oto demo na żywo w plunkerze - „Prosty przykład o @HostListener i @HostBinding”

  • Ten przykład wiąże rolewłaściwość - zadeklarowaną za pomocą @HostBinding- z elementem hosta
    • Przypomnij sobie, że rolejest to atrybut, ponieważ używamy attr.role.
    • <p myDir>staje się, <p mydir="" role="admin">gdy przeglądasz go w narzędziach programistycznych.
  • Następnie nasłuchuje onClickzdarzenia zadeklarowanego za pomocą @HostListener, dołączonego do elementu hosta komponentu, zmieniającego rolesię po każdym kliknięciu.
    • Zmiana po <p myDir>kliknięciu polega na tym, że jego otwierający znacznik zmienia się z <p mydir="" role="admin">na <p mydir="" role="guest">iz powrotem.

dyrektywy.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
czy ten dekorator jest nadal używany, wygląda na to, że linki zostały usunięte z dokumentacji
angular2

1
Tak, jest nadal w użyciu, ale pozwolę sobie raz to potwierdzić. Powiadomię cię, jeśli coś wymyślę.
micronyks


1
@ Mr.EasyAnswersMcFly zaktualizowana odpowiedź z notatką i linkiem. Należy pamiętać, że nadal nie jest dostępna odpowiednia dokumentacja.
micronyks

1
@MuhammadSaleh za przewijanie trudno powiedzieć, jak to liczy i oblicza ... ale na pewno każda instancja będzie miała oddzielnego słuchacza
micronyks

117

Szybka wskazówka, która pomaga mi zapamiętać, co robią -

HostBinding('value') myValue; jest dokładnie taki sam jak [value]="myValue"

I

HostListener('click') myClick(){ } jest dokładnie taki sam jak (click)="myClick()"


HostBindingi HostListenersą napisane w dyrektywach i innych (...)oraz [..]są napisane wewnątrz szablonów (komponentów).


9
Ach, to zaskoczyło mnie dzięki tej odpowiedzi. @HostListenerjest drogą do zrobienia, gdy nie masz nic na DOM dla typowego powiązania zdarzeń, takich jak wejście z klawiatury w moim przypadku.
MrBoJangles,

47

Oto podstawowy przykład najechania kursorem.

Właściwość szablonu komponentu:

Szablon

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

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

I nasza dyrektywa

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
Nie widzę tej zaakceptowanej odpowiedzi jako odpowiedzi na zadane pytanie. Czy zechciałbyś podać jakieś wyjaśnienie? Na przykład co c_colorrr, c_onEnterrr (), c_onLeaveeee robią w tym konkretnym fragmencie kodu?
luqo33

1
Myślę, że powinno zmienić kolor po wejściu myszy na niebieski, a po opuszczeniu zdarzenia na żółty.
Michał Ziobro

Gdzie umieszczasz dyrektywę w znacznikach? Wygląda na to, że umieścisz go na tagu body, ale będzie to poza głównym komponentem. Jeśli jesteś zdezorientowany tą odpowiedzią, ten link może pomóc ng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding
mtpultz

@mtpultz To jest w klasie.
serkan

33

Kolejną fajną rzeczą @HostBindingjest to, że możesz to połączyć z, @Inputjeśli twoje powiązanie opiera się bezpośrednio na wejściu, np:

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

1
Czy możesz podzielić się przykładem użycia z @Input()?
Mano

Przykład jest w mojej odpowiedzi, po prostu piszesz do obu dekoratorów jeden po drugim, porządek powinien być nieistotny
altschuler

1
Myślę, że brakuje mi tego, czym różni się to od zwykłego użycia @HostBinding. Kiedy potrzebujesz użyć @Input?
1252748

12

Jedną rzeczą, która wprowadza zamieszanie w tym temacie, jest to, że idea dekoratorów nie jest zbyt jasna, a kiedy rozważamy coś takiego ...

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

Działa, ponieważ jest getakcesorium . Nie możesz użyć odpowiednika funkcji:

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

W przeciwnym razie zaletą używania @HostBindingjest zapewnienie wykrywania zmian, gdy zmienia się wartość powiązana.


9

Podsumowanie:

  • @HostBinding: Ten dekorator wiąże właściwość klasy z właściwością elementu hosta.
  • @HostListener: Ten dekorator wiąże metodę klasy ze zdarzeniem elementu hosta.

Przykład:

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';
  }

}

W powyższym przykładzie zachodzi następująca sytuacja:

  • Do zdarzenia kliknięcia dodawany jest detektor zdarzeń, który będzie uruchamiany, gdy zdarzenie kliknięcia wystąpi w dowolnym miejscu w komponencie
  • colorNieruchomość w naszej AppComponentklasie jest związany z style.colorposesji na komponencie. Więc gdy colorwłaściwość jest aktualizowana, tak samo będziestyle.color właściwością naszego komponentu
  • W rezultacie za każdym razem, gdy ktoś kliknie komponent, kolor zostanie zaktualizowany.

Wykorzystanie w @Directive:

Chociaż może być używany na komponencie, te dekoratory są często używane w dyrektywach atrybutów. Użycie w @Directivehoście zmienia element, w którym znajduje się dyrektywa. Na przykład spójrz na ten szablon komponentu:

<p p_Dir>some paragraph</p>

Tutaj p_Dir jest dyrektywą dotyczącą <p>elementu. Gdy @HostBindinglub @HostListenerjest używane w klasie dyrektywy, host będzie teraz odwoływał się do <p>.


6

Teoria z mniejszą liczbą żargonów

@Hostlistnening zajmuje się w zasadzie z elementem hosta, powiedzmy (przycisk), słuchając akcji użytkownika i wykonując określoną funkcję powiedz alert („Ahoy!”), Podczas gdy @Hostbinding jest odwrotnie. Tutaj słuchamy zmian, które zaszły na tym przycisku wewnętrznie (powiedz, kiedy został kliknięty, co stało się z klasą) i używamy tej zmiany, aby zrobić coś innego, na przykład wyemitować określony kolor.

Przykład

Pomyśl o scenariuszu, w którym chciałbyś stworzyć ulubioną ikonę na komponencie, teraz wiesz, że musisz wiedzieć, czy przedmiot został dodany do ulubionych ze zmienioną klasą, potrzebujemy sposobu, aby to ustalić. Właśnie w tym miejscu pojawia się @Hostbinding.

A tam, gdzie trzeba wiedzieć, jaka akcja została faktycznie wykonana przez użytkownika, właśnie wtedy pojawia się @Hostlistening


3
To jest mylące, a nazwy dekoratorów są niedokładne.
matmancini
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.