@HostBinding et @HostListener: que font-ils et à quoi servent-ils?


188

Dans mes méandres à travers le monde entier interweb, et maintenant surtout les documents de style angular.io , je trouve de nombreuses références à @HostBindinget @HostListener. Il semble qu'ils soient assez fondamentaux, mais malheureusement, la documentation les concernant pour le moment est un peu sommaire.

Quelqu'un peut-il expliquer ce qu'ils sont, comment ils fonctionnent et donner un exemple de leur utilisation?

Réponses:


139

Avez-vous vérifié ces documents officiels?

HostListener - Déclare un écouteur hôte. Angular appellera la méthode décorée lorsque l'élément hôte émettra l'événement spécifié.

@HostListener- écoutera l'événement émis par l'élément hôte déclaré avec @HostListener.

HostBinding - Déclare une liaison de propriété d'hôte. Angular vérifie automatiquement les liaisons des propriétés de l'hôte lors de la détection des modifications. Si une liaison change, elle mettra à jour l'élément hôte de la directive.

@HostBinding- liera la propriété à l'élément hôte, si une liaison change, HostBindingmettra à jour l'élément hôte.


REMARQUE: les deux liens ont été supprimés récemment. La partie " HostBinding-HostListening " du guide de style peut être une alternative utile jusqu'au retour des liens.


Voici un exemple de code simple pour vous aider à comprendre ce que cela signifie:

DEMO: Voici la démo en direct dans plunker - "Un exemple simple sur @HostListener & @HostBinding"

  • Cet exemple lie une rolepropriété - déclarée avec @HostBinding- à l'élément de l'hôte
    • Rappelez-vous que rolec'est un attribut, puisque nous utilisons attr.role.
    • <p myDir>devient <p mydir="" role="admin">lorsque vous l'affichez dans les outils de développement.
  • Il écoute ensuite l' onClickévénement déclaré avec @HostListener, attaché à l'élément hôte du composant, changeant roleà chaque clic.
    • Le changement lorsque l'utilisateur <p myDir>clique sur est que sa balise d'ouverture change de <p mydir="" role="admin">à <p mydir="" role="guest">et de retour.

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
ce décorateur est-il toujours utilisé il semble que les liens ont été supprimés de la documentation
angular2

1
Oui, il est toujours utilisé mais permettez-moi de le confirmer une fois. Je vais vous mettre à jour, si je peux trouver autre chose.
micronyks

Ils sont sur la feuille de triche: angular.io/docs/ts/latest/guide/cheatsheet.html
Targaryen

1
@ Mr.EasyAnswersMcFly réponse mise à jour avec note et lien. Veuillez noter que la documentation appropriée n'est toujours pas disponible.
micronyks

1
@MuhammadSaleh pour faire défiler il est difficile de dire que comment il compte et calcule ... mais c'est sûr que chaque instance aura un auditeur séparé
micronyks

112

Un petit conseil qui m'aide à me souvenir de ce qu'ils font -

HostBinding('value') myValue; est exactement le même que [value]="myValue"

Et

HostListener('click') myClick(){ } est exactement le même que (click)="myClick()"


HostBindinget HostListenersont écrits dans des directives et les autres (...)et [..]sont écrits dans des modèles (de composants).


9
Ah, ça a cliqué (jeu de mots) avec moi grâce à cette réponse. @HostListenerest la voie à suivre lorsque vous n'avez rien sur le DOM pour la liaison d'événement typique, comme la saisie au clavier dans mon cas.
MrBoJangles

47

Voici un exemple de survol de base.

Propriété de modèle du composant:

Modèle

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

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

Et notre directive

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
Je ne vois pas cette réponse acceptée comme une réponse à la question posée. Souhaitez-vous fournir des explications? Comme ce que font c_colorrr, c_onEnterrr (), c_onLeaveeee dans cet extrait de code particulier?
luqo33

1
Je pense qu'il devrait changer la couleur de l'événement d'entrée de la souris en bleu et de l'événement de sortie de la souris en jaune.
Michał Ziobro

Où placez-vous la directive dans le balisage? Il semble que vous le placeriez sur la balise body, mais ce serait en dehors du composant racine. Si vous êtes confus par cette réponse, ce lien pourrait aider ng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding
mtpultz

@mtpultz C'est dans la classe.
serkan

33

Une autre chose intéressante @HostBindingest que vous pouvez le combiner avec @Inputsi votre liaison repose directement sur une entrée, par exemple:

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

1
Pouvez-vous s'il vous plaît partager un exemple d'utilisation avec @Input()?
Mano

L'exemple est juste là dans ma réponse, vous écrivez simplement les deux décorateurs l'un après l'autre, l'ordre ne devrait pas être pertinent
altschuler

1
Je pense que ce qui me manque, c'est en quoi cela diffère de la simple utilisation @HostBinding. Quand avez-vous besoin de l'utiliser @Input?
1252748

11

Une chose qui ajoute de la confusion à ce sujet est que l'idée des décorateurs n'est pas très claire, et quand on considère quelque chose comme ...

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

Cela fonctionne, car c'est un getaccesseur . Vous ne pouvez pas utiliser une fonction équivalente:

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

Sinon, l'avantage de l'utilisation @HostBindingest qu'elle garantit que la détection des modifications est exécutée lorsque la valeur liée change.


9

Résumé:

  • @HostBinding: Ce décorateur lie une propriété de classe à une propriété de l'élément hôte.
  • @HostListener: Ce décorateur lie une méthode de classe à un événement de l'élément hôte.

Exemple:

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

}

Dans l'exemple ci-dessus, ce qui suit se produit:

  • Un écouteur d'événement est ajouté à l'événement de clic qui sera déclenché lorsqu'un événement de clic se produit n'importe où dans le composant
  • La colorpropriété de notre AppComponentclasse est liée à la style.colorpropriété du composant. Ainsi, chaque fois que la colorpropriété est mise à jour, la style.colorpropriété de notre composant le sera aussi
  • Le résultat sera que chaque fois que quelqu'un cliquera sur le composant, la couleur sera mise à jour.

Utilisation en @Directive:

Bien qu'il puisse être utilisé sur un composant, ces décorateurs sont souvent utilisés dans des directives d'attribut. Lorsqu'il est utilisé dans un @Directivehôte, l'élément sur lequel la directive est placée change. Par exemple, jetez un œil à ce modèle de composant:

<p p_Dir>some paragraph</p>

Ici, p_Dir est une directive sur l' <p>élément. Lorsque @HostBindingou @HostListenerest utilisé dans la classe de directive, l'hôte fera désormais référence au <p>.


6

Théorie avec moins de jargons

@Hostlistnening traite essentiellement de l'élément hôte, disons (un bouton), écoutant une action d'un utilisateur et exécutant une certaine fonction, disons alert ("Ahoy!"), Tandis que @Hostbinding est l'inverse. Ici, nous écoutons les changements qui se sont produits sur ce bouton en interne (dites quand on a cliqué sur ce qui est arrivé à la classe) et nous utilisons ce changement pour faire autre chose, par exemple émettre une couleur particulière.

Exemple

Pensez au scénario dans lequel vous souhaitez créer une icône préférée sur un composant, maintenant vous savez que vous devez savoir si l'élément a été ajouté aux favoris avec sa classe modifiée, nous avons besoin d'un moyen de le déterminer. C'est exactement là qu'intervient @Hostbinding.

Et là où il est nécessaire de savoir quelle action a réellement été effectuée par l'utilisateur, c'est là qu'intervient @Hostlistening


3
C'est déroutant et les noms des décorateurs sont inexacts.
matmancini
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.