@HostBinding y @HostListener: ¿qué hacen y para qué sirven?

188

En mis meandros alrededor de la red mundial, y ahora especialmente en los documentos de estilo angular.io , encuentro muchas referencias a @HostBindingy @HostListener. Parece que son bastante fundamentales, pero desafortunadamente la documentación para ellos en este momento es un poco incompleta.

¿Alguien puede explicar qué son, cómo funcionan y dar un ejemplo de su uso?

serlingpa
fuente

Respuestas:

139

¿Has consultado estos documentos oficiales?

HostListener : declara un escucha de host. Angular invocará el método decorado cuando el elemento host emite el evento especificado.

@HostListener- escuchará el evento emitido por el elemento host que se declara con @HostListener.

HostBinding : declara un enlace de propiedad de host. Angular verifica automáticamente los enlaces de propiedades del host durante la detección de cambios. Si un enlace cambia, actualizará el elemento host de la directiva.

@HostBinding- enlazará la propiedad al elemento host. Si cambia un enlace, HostBindingactualizará el elemento host.


NOTA: Ambos enlaces se han eliminado recientemente. La parte " HostBinding-HostListening " de la guía de estilo puede ser una alternativa útil hasta que regresen los enlaces.


Aquí hay un ejemplo de código simple para ayudar a imaginar lo que esto significa:

DEMO: Aquí está la demostración en vivo en plunker - "Un ejemplo simple sobre @HostListener y @HostBinding"

  • Este ejemplo vincula una rolepropiedad, declarada con @HostBinding, al elemento del host
    • Recordemos que rolees un atributo, ya que estamos usando attr.role.
    • <p myDir>se convierte <p mydir="" role="admin">cuando lo ve en las herramientas de desarrollador.
  • Luego escucha el onClickevento declarado con @HostListener, adjunto al elemento host del componente, cambiando rolecon cada clic.
    • El cambio cuando el <p myDir>se hace clic es que su etiqueta de apertura cambia de <p mydir="" role="admin">a <p mydir="" role="guest">ida y vuelta.

directivas.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 {}
micronyks
fuente
1
si este decorador todavía se usa, parece que los enlaces se han eliminado de la documentación angular2
CommonSenseCode
1
Sí, todavía está en uso, pero déjame confirmarlo una vez. Te actualizaré, si puedo encontrar otra cosa.
micronyks
Están en la hoja de trucos: angular.io/docs/ts/latest/guide/cheatsheet.html
Targaryen
1
@ Mr.EasyAnswersMcFly respuesta actualizada con nota y enlace. Tenga en cuenta que la documentación adecuada aún no está disponible.
micronyks
1
@MuhammadSaleh de desplazamiento es difícil decir que la forma en que cuenta y calcula ... pero eso es para asegurarse de que cada instancia tendrá un oyente separada
micronyks
112

Un consejo rápido que me ayuda a recordar lo que hacen:

HostBinding('value') myValue; es exactamente lo mismo que [value]="myValue"

Y

HostListener('click') myClick(){ } es exactamente lo mismo que (click)="myClick()"


HostBindingy HostListenerestán escritas en directivas y otras, (...)y [..]están escritas dentro de plantillas (de componentes).

Shai Reznik - HiRez.io
fuente
9
Ah, hizo clic (juego de palabras) conmigo gracias a esta respuesta. @HostListeneres el camino a seguir cuando no tiene nada en el DOM para el enlace de eventos típico, como la entrada de teclado en mi caso.
MrBoJangles
47

Aquí hay un ejemplo básico de desplazamiento.

Propiedad de plantilla del componente:

Modelo

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

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

Y nuestra directiva

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" ;
  } 
}
serkan
fuente
28
No veo esta respuesta aceptada como una respuesta a la pregunta formulada. ¿Te gustaría dar alguna explicación? ¿Como lo que hacen c_colorrr, c_onEnterrr (), c_onLeaveeee en este fragmento de código en particular?
luqo33
1
Creo que debería cambiar el color en el evento de ingreso del mouse a azul y en el evento de dejar el mouse a amarillo.
Michał Ziobro
¿Dónde coloca la directiva en el marcado? Parece que lo colocarías en la etiqueta del cuerpo, pero eso estaría fuera del componente raíz. Si está confundido por esta respuesta, este enlace podría ayudar ng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding
mtpultz
@mtpultz Está en la clase.
serkan
33

Otra cosa interesante @HostBindinges que puede combinarlo @Inputsi su enlace se basa directamente en una entrada, por ejemplo:

@HostBinding('class.fixed-thing')
@Input()
fixed: boolean;
Altschuler
fuente
1
¿Puedes compartir un ejemplo de uso con @Input()?
Mano
El ejemplo está ahí en mi respuesta, simplemente escribes ambos decoradores uno tras otro, el orden debe ser irrelevante
altschuler
1
Creo que lo que me falta es cómo esto difiere del uso @HostBinding. ¿Cuándo necesitas usar @Input?
1252748
11

Una cosa que agrega confusión a este tema es que la idea de decoradores no está muy clara, y cuando consideramos algo como ...

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

Funciona porque es un getaccesorio . No podría usar una función equivalente:

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

De lo contrario, el beneficio del uso @HostBindinges que garantiza que la detección de cambios se ejecute cuando cambie el valor enlazado.

Hecho
fuente
9

Resumen:

  • @HostBinding: Este decorador vincula una propiedad de clase a una propiedad del elemento host.
  • @HostListener: Este decorador vincula un método de clase a un evento del elemento host.

Ejemplo:

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

}

En el ejemplo anterior ocurre lo siguiente:

  • Se agrega un detector de eventos al evento de clic que se activará cuando se produzca un evento de clic en cualquier lugar dentro del componente
  • La colorpropiedad en nuestra AppComponentclase está vinculada a la style.colorpropiedad en el componente. Entonces, cada vez que colorse actualiza la style.colorpropiedad, también lo hará la propiedad de nuestro componente
  • El resultado será que cada vez que alguien haga clic en el componente, el color se actualizará.

Uso en @Directive:

Aunque puede usarse en componentes, estos decoradores a menudo se usan en directivas de atributo. Cuando se usa en un @Directivehost, el elemento cambia el elemento en el que se coloca la directiva. Por ejemplo, eche un vistazo a esta plantilla de componente:

<p p_Dir>some paragraph</p>

Aquí p_Dir es una directiva sobre el <p>elemento. Cuando @HostBindingo @HostListenerse usa dentro de la clase directiva, el host ahora se referirá a <p>.

Willem van der Veen
fuente
6

Teoría con menos Jargons

@Hostlistnening trata básicamente con el elemento host decir (un botón) escuchar una acción de un usuario y realizar una determinada función decir alerta ("¡Ahoy!") Mientras que @Hostbinding es al revés. Aquí escuchamos los cambios que ocurrieron en ese botón internamente (digamos cuando se hizo clic en lo que sucedió con la clase) y usamos ese cambio para hacer otra cosa, por ejemplo, emitir un color particular.

Ejemplo

Piensa en el escenario en el que te gustaría hacer un ícono favorito en un componente, ahora sabes que tendrías que saber si el elemento ha sido favorecido con su clase cambiada, necesitamos una forma de determinar esto. Ahí es exactamente donde entra @Hostbinding.

Y donde existe la necesidad de saber qué acción fue realmente realizada por el usuario, ahí es donde entra @Hostlistening

Ralphkay
fuente
3
Esto es confuso, y los nombres de los decoradores son inexactos.
matmancini