@HostBinding e @HostListener: cosa fanno e a cosa servono?


188

Nei miei meandri in tutto il mondo, e ora specialmente i documenti di stile angular.io , trovo molti riferimenti a @HostBindinge @HostListener. Sembra che siano piuttosto fondamentali, ma sfortunatamente la documentazione per loro al momento è un po 'imprecisa.

Qualcuno può spiegare cosa sono, come funzionano e dare un esempio del loro utilizzo?

Risposte:


139

Hai controllato questi documenti ufficiali?

HostListener : dichiara un listener host. Angular invocherà il metodo decorato quando l'elemento host emette l'evento specificato.

@HostListener- ascolterà l'evento emesso dall'elemento host dichiarato con @HostListener.

HostBinding : dichiara un'associazione di proprietà host. Angular controlla automaticamente i binding delle proprietà dell'host durante il rilevamento delle modifiche. Se un'associazione cambia, aggiornerà l'elemento host della direttiva.

@HostBinding- vincolerà la proprietà all'elemento host, se un'associazione cambia, HostBindingaggiornerà l'elemento host.


NOTA: entrambi i collegamenti sono stati rimossi di recente. La parte " HostBinding-HostListening " della guida di stile può essere un'alternativa utile fino alla restituzione dei collegamenti.


Ecco un semplice esempio di codice per aiutare a capire cosa significa:

DEMO: Ecco la demo live in plunker - "Un semplice esempio di @HostListener & @HostBinding"

  • Questo esempio associa una roleproprietà - dichiarata con @HostBinding- all'elemento host
    • Ricordiamo che roleè un attributo, poiché stiamo usando attr.role.
    • <p myDir>diventa <p mydir="" role="admin">quando lo visualizzi negli strumenti di sviluppo.
  • Quindi ascolta l' onClickevento dichiarato con @HostListener, associato all'elemento host del componente, cambiando rolead ogni clic.
    • Il cambiamento quando la <p myDir>si fa clic è che il suo tag di apertura cambia da <p mydir="" role="admin">a <p mydir="" role="guest">e ritorno.

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
questo decoratore è ancora usato sembra che i collegamenti siano stati rimossi dalla documentazione angular2
CommonSenseCode

1
Sì, è ancora in uso ma lasciami confermare una volta. Ti aggiornerò, se riesco a capire qualcos'altro.
micronyks,


1
@ Mr.EasyAnswersMcFly risposta aggiornata con nota e collegamento. Si noti che non è ancora disponibile la documentazione corretta.
micronyks,

1
@MuhammadSaleh per scorrere è difficile dire che conta e calcola ... ma questo è certo che ogni istanza avrà un ascoltatore separato
micronyks il

112

Un suggerimento rapido che mi aiuta a ricordare cosa fanno -

HostBinding('value') myValue; è esattamente lo stesso di [value]="myValue"

E

HostListener('click') myClick(){ } è esattamente lo stesso di (click)="myClick()"


HostBindinge HostListenersono scritti nelle direttive e negli altri (...)e [..]sono scritti all'interno di modelli (di componenti).


9
Ah, ha fatto clic (gioco di parole intenzionale) con me grazie a questa risposta. @HostListenerè la strada da percorrere quando non hai nulla sul DOM per il tipico binding di eventi, come l'input da tastiera nel mio caso.
MrBoJangles,

47

Ecco un esempio di hover di base.

Proprietà modello del componente:

Modello

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

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

E la nostra direttiva

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
Non vedo questa risposta accettata come una risposta alla domanda posta. Ti andrebbe di fornire qualche spiegazione? Come cosa fanno c_colorrr, c_onEnterrr (), c_onLeaveeee in questo particolare frammento di codice?
luqo33,

1
Penso che dovrebbe cambiare colore al mouse, inserire l'evento in blu e al mouse lasciare l'evento in giallo.
Michał Ziobro,

Dove si inserisce la direttiva nel markup? Sembra che lo posizioneresti sul tag body, ma sarebbe al di fuori del componente radice. Se sei confuso da questa risposta, questo link potrebbe aiutare ng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding
mtpultz

@mtpultz È nella classe.
serkan,

33

Un'altra cosa interessante @HostBindingè che puoi combinarlo con @Inputse la tua associazione si basa direttamente su un input, ad esempio:

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

1
Puoi condividere un esempio sull'utilizzo con @Input()?
Mano,

L'esempio è proprio lì nella mia risposta, scrivi semplicemente entrambi i decoratori uno dopo l'altro, l'ordine dovrebbe essere irrilevante
altschuler

1
Penso che ciò che mi manca è come questo differisca dal solo uso @HostBinding. Quando hai bisogno di usare @Input?
1252748

11

Una cosa che aggiunge confusione a questo argomento è che l'idea dei decoratori non è molto chiara e quando consideriamo qualcosa come ...

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

Funziona perché è un getaccessor . Non è possibile utilizzare una funzione equivalente:

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

Altrimenti, il vantaggio dell'utilizzo @HostBindingè che assicura che il rilevamento delle modifiche venga eseguito quando il valore associato cambia.


9

Sommario:

  • @HostBinding: Questo decoratore associa una proprietà di classe a una proprietà dell'elemento host.
  • @HostListener: Questo decoratore associa un metodo di classe a un evento dell'elemento host.

Esempio:

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

}

Nell'esempio sopra si verifica quanto segue:

  • Un listener di eventi viene aggiunto all'evento click che verrà generato quando si verifica un evento click all'interno del componente
  • La colorproprietà nella nostra AppComponentclasse è associata alla style.colorproprietà sul componente. Quindi, ogni volta che la colorproprietà viene aggiornata, anche la style.colorproprietà del nostro componente
  • Il risultato sarà che ogni volta che qualcuno fa clic sul componente, il colore verrà aggiornato.

Utilizzo in @Directive:

Sebbene possano essere utilizzati sui componenti, questi decoratori vengono spesso utilizzati nelle direttive di attributo. Se utilizzato in un @Directivehost, cambia l'elemento su cui è posizionata la direttiva. Ad esempio, dai un'occhiata a questo modello di componente:

<p p_Dir>some paragraph</p>

Qui p_Dir è una direttiva <p>sull'elemento. Quando @HostBindingo @HostListenerviene utilizzato all'interno della classe direttiva, l'host farà ora riferimento a <p>.


6

Teoria con meno gerghi

@Hostlistnening si occupa fondamentalmente dell'elemento host say (un pulsante) che ascolta un'azione da parte di un utente ed esegue una determinata funzione say alert ("Ahoy!") Mentre @Hostbinding è il contrario. Qui ascoltiamo le modifiche che sono avvenute su quel pulsante internamente (dì quando è stato cliccato cosa è successo alla classe) e usiamo quella modifica per fare qualcos'altro, diciamo emettere un colore particolare.

Esempio

Pensa allo scenario in cui desideri creare un'icona preferita su un componente, ora sai che dovresti sapere se l'elemento è stato favorito con la sua classe modificata, abbiamo bisogno di un modo per determinarlo. È esattamente qui che entra in gioco @Hostbinding.

E dove c'è la necessità di sapere quale azione è stata effettivamente eseguita dall'utente, è qui che entra in gioco @Hostlistening


3
Questo è confuso e i nomi dei decoratori non sono accurati.
matmancini,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.