@HostBinding и @HostListener: что они делают и для чего?

В моем блуждании по всему миру, а теперь особенно в документах в стиле angular.io, я нахожу много ссылок в @HostBinding и @HostListener. Они кажутся довольно фундаментальными, но, к сожалению, документация по ним на данный момент немного отрывочна.

Может ли кто-нибудь объяснить, что это такое, как они работают, и привести пример их использования?


person serlingpa    schedule 22.06.2016    source источник


Ответы (9)


Вы проверили эти официальные документы?

HostListener - объявляет слушателя хоста. Angular вызовет декорированный метод, когда элемент хоста испускает указанное событие.

@HostListener - будет прослушивать событие, генерируемое элементом хоста, объявленным с помощью @HostListener.

HostBinding - объявляет привязку свойства хоста. Angular автоматически проверяет привязки свойств хоста во время обнаружения изменений. Если привязка изменится, она обновит хост-элемент директивы.

@HostBinding - привяжет свойство к элементу хоста. Если привязка изменится, HostBinding обновит элемент хоста.


ПРИМЕЧАНИЕ. Обе ссылки недавно были удалены. Часть руководства по стилю "HostBinding-HostListening" может быть полезная альтернатива, пока ссылки не вернутся.


Вот простой пример кода, который помогает понять, что это означает:

ДЕМО: Вот демонстрация в плункере - «Простой пример о @HostListener и @HostBinding»

  • This example binds a role property -- declared with @HostBinding -- to the host's element
    • Recall that role is an attribute, since we're using attr.role.
    • <p myDir> становится <p mydir="" role="admin">, когда вы просматриваете его в инструментах разработчика.
  • It then listens to the onClick event declared with @HostListener, attached to the component's host element, changing role with each click.
    • The change when the <p myDir> is clicked is that its opening tag changes from <p mydir="" role="admin"> to <p mydir="" role="guest"> and back.

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 {}
person micronyks    schedule 22.06.2016
comment
этот декоратор все еще используется, кажется, ссылки были удалены из документации angular2 - person CommonSenseCode; 19.09.2016
comment
Да, он все еще используется, но позвольте мне подтвердить это еще раз. Я сообщу вам, если смогу придумать что-нибудь еще. - person micronyks; 20.09.2016
comment
Они находятся в шпаргалке: angular.io/docs/ts/latest/guide /cheatsheet.html - person Targaryen; 21.09.2016
comment
@ Mr.EasyAnswersMcFly обновил ответ с примечанием и ссылкой. Обратите внимание, что до сих пор нет надлежащей документации. - person micronyks; 22.09.2016
comment
@micronyks За то, что вы только что сказали в ответе. Где я могу найти для этого документ? Спасибо! - person Nicolas S.Xu; 29.11.2016
comment
Ребята, вопрос производительности. Если я использовал @HostListener с событием прокрутки окна внутри директивы и было несколько экземпляров этой директивы, будет ли прослушиватель событий привязан ко всем экземплярам, ​​или у него будет только один прослушиватель и будут запускать методы внутри этого? - person Muhammad Saleh; 25.12.2016
comment
@MuhammadSaleh, пожалуйста, покажите, что практически сложно угадать и ответить. - person micronyks; 25.12.2016
comment
@micronyks Пожалуйста, проверьте этот Plunkr Пожалуйста, проверьте его консоль В этом примере у меня есть несколько экземпляров та же директива Итак, мой вопрос: означает ли это, что у меня будет несколько прослушивателей событий, прослушивающих событие прокрутки [я полагаю, плохая производительность] или Angular достаточно умен, чтобы иметь один глобальный прослушиватель событий прокрутки окна и просто выполнять методы внутри , или это не имеет большого значения? - person Muhammad Saleh; 25.12.2016
comment
@MuhammadSaleh для прокрутки трудно сказать, как он считает и вычисляет ... но это точно, что у каждого экземпляра будет отдельный слушатель - person micronyks; 25.12.2016
comment
Если кто-то ищет пример, я быстро прочитал его, и внизу вы можете вырезать, вставить и поиграть с кодом - ng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding - person mtpultz; 06.07.2017
comment
Я не думаю, что для @Component есть атрибут directives - person tmjee; 27.10.2017

Небольшой совет, который помогает мне вспомнить, что они делают -

HostBinding('value') myValue; в точности совпадает с [value]="myValue"

А также

HostListener('click') myClick(){ } в точности совпадает с (click)="myClick()"


HostBinding и HostListener записываются в директивах, а остальные (...) и [..] записываются внутри шаблонов (компонентов).

person Shai Reznik - HiRez.io    schedule 17.10.2017
comment
Ах, это мне понравилось (каламбур) благодаря этому ответу. @HostListener - это то, что нужно, когда у вас нет ничего в DOM для типичной привязки событий, например, ввода с клавиатуры в моем случае. - person MrBoJangles; 18.02.2018

Вот простой пример наведения.

Свойство шаблона компонента:

Шаблон

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

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

И наша директива

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" ;
  } 
}
person serkan    schedule 14.01.2017
comment
Я не считаю этот принятый ответ ответом на заданный вопрос. Не могли бы вы дать какое-нибудь объяснение? Например, что c_colorrr, c_onEnterrr (), c_onLeaveeee делают в этом конкретном фрагменте кода? - person luqo33; 05.05.2017
comment
Я думаю, он должен изменить цвет при входе мыши на синий, а при выходе мыши на желтый. - person Michał Ziobro; 08.05.2017
comment
Где вы размещаете директиву в разметке? Кажется, вы разместите его в теге body, но это будет вне корневого компонента. Если вас смущает этот ответ, эта ссылка может помочь ng2.codecraft. tv / custom-directives / hostlistener-and-hostbinding - person mtpultz; 06.07.2017
comment
@mtpultz Это в классе. - person serkan; 06.08.2017

Еще одна приятная особенность @HostBinding заключается в том, что вы можете комбинировать его с @Input, если ваша привязка напрямую зависит от ввода, например:

@HostBinding('class.fixed-thing')
@Input()
fixed: boolean;
person altschuler    schedule 15.11.2016
comment
Не могли бы вы поделиться примером использования с @Input()? - person Mano; 27.07.2018
comment
Пример прямо в моем ответе, вы просто пишете оба декоратора один за другим, порядок не должен иметь значения - person altschuler; 29.07.2018
comment
Я думаю, что мне не хватает того, чем это отличается от простого использования @HostBinding. Когда вам нужно использовать @Input? - person 1252748; 01.06.2020

Резюме:

  • @HostBinding: этот декоратор связывает свойство класса со свойством ведущего элемента.
  • @HostListener: этот декоратор связывает метод класса с событием элемента хоста.

Пример:

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

}

В приведенном выше примере происходит следующее:

  • К событию щелчка добавляется прослушиватель событий, который запускается, когда событие щелчка происходит в любом месте компонента.
  • Свойство color в нашем классе AppComponent привязано к свойству style.color компонента. Поэтому всякий раз, когда свойство color обновляется, свойство style.color нашего компонента
  • В результате всякий раз, когда кто-то щелкает по компоненту, цвет будет обновляться.

Использование в @Directive:

Хотя их можно использовать в компонентах, эти декораторы часто используются в директивах атрибутов. При использовании в @Directive хост изменяет элемент, на котором размещена директива. Например, взгляните на этот шаблон компонента:

<p p_Dir>some paragraph</p>

Здесь p_Dir - это директива для элемента <p>. Когда @HostBinding или @HostListener используется в классе директивы, хост теперь будет ссылаться на <p>.

person Willem van der Veen    schedule 20.10.2018

Одна вещь, которая добавляет путаницы в этот предмет, - это то, что идея декораторов не очень ясна, и когда мы рассматриваем что-то вроде ...

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

Это работает, потому что это get аксессор. Вы не могли использовать эквивалент функции:

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

В противном случае преимущество использования @HostBinding заключается в том, что он гарантирует, что обнаружение изменений запускается при изменении связанного значения.

person Community    schedule 11.11.2016

Теория без жаргона

@Hostlistnening в основном имеет дело с элементом хоста say (кнопка), который слушает действие пользователя и выполняет определенную функцию say alert («Эй!»), А @Hostbinding - наоборот. Здесь мы слушаем изменения, которые произошли на этой кнопке внутри (скажем, когда она была нажата, что произошло с классом), и мы используем это изменение, чтобы сделать что-то еще, например, испустить определенный цвет.

Пример

Подумайте о сценарии, в котором вы хотели бы сделать значок избранного для компонента, теперь вы знаете, что вам нужно знать, был ли элемент добавлен в избранное с измененным его классом, нам нужен способ определить это. Именно здесь на помощь приходит @Hostbinding.

И где нужно знать, какое действие на самом деле было выполнено пользователем, именно здесь появляется @Hostlistening.

person Ralphkay    schedule 19.01.2017
comment
Это сбивает с толку, а имена декораторов неточны. - person matmancini; 02.02.2018

МЕТОД ДЕКОРАТОРА:

@HostBinding: динамическая привязка настраиваемой логики к элементу Host

 @HostBinding('class.active')
 activeClass = false;

@HostListen: для прослушивания событий на элементе Host

@HostListener('click')
 activeFunction(){
    this.activeClass = !this.activeClass;
 }

Хост-элемент:

  <button type='button' class="btn btn-primary btn-sm" appHost>Host</button>
person rohit.khurmi095    schedule 08.02.2021

person    schedule
comment
Спасибо за ответ. Не могли бы вы отредактировать свой ответ на, включив в него объяснение кода? Это поможет будущим читателям лучше понять, что происходит, и особенно тем членам сообщества, которые плохо знакомы с языком и изо всех сил пытаются понять концепции. - person sta; 04.02.2021