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

188

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

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

serlingpa
источник

Ответы:

139

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

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

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

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

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


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


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

ДЕМО: Вот демо-версия live in plunker - «Простой пример @HostListener & @HostBinding»

  • В этом примере привязывается roleсвойство - объявлено с @HostBinding- к элементу хоста
    • Напомним, что roleэто атрибут, так как мы используем attr.role.
    • <p myDir>становится, <p mydir="" role="admin">когда вы просматриваете его в инструментах разработчика.
  • Затем он прослушивает onClickсобытие, объявленное с помощью @HostListener, прикрепленного к элементу хоста компонента, и изменяется roleс каждым щелчком.
    • Изменение при <p myDir>нажатии заключается в том, что его открывающий тег изменяется с <p mydir="" role="admin">на <p mydir="" role="guest">и обратно.

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 {}
micronyks
источник
1
этот декоратор все еще используется, кажется, что ссылки были удалены из документации
angular2
1
Да, он все еще используется, но позвольте мне подтвердить это один раз. Я сообщу вам, если смогу выяснить что-то еще.
Микроникс 20.09.16
Они находятся на шпаргалку: angular.io/docs/ts/latest/guide/cheatsheet.html
Targaryen
1
@ Mr.EasyAnswersMcFly обновленный ответ с примечанием и ссылкой. Обратите внимание, что надлежащая документация по-прежнему недоступна.
Микроникс 22.09.16
1
@MuhammadSaleh для прокрутки трудно сказать, как он считает и рассчитывает ... но это точно, что у каждого экземпляра будет отдельный слушатель
micronyks
112

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

HostBinding('value') myValue; точно так же, как [value]="myValue"

И

HostListener('click') myClick(){ } точно так же, как (click)="myClick()"


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

Шай Резник - HiRez.io
источник
9
Ах, это щелкнуло (каламбур) со мной благодаря этому ответу. @HostListenerэто путь, когда у вас нет ничего в DOM для типичной привязки событий, таких как ввод с клавиатуры в моем случае.
MrBoJangles
47

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

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

шаблон

<!-- 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" ;
  } 
}
Серкан
источник
28
Я не вижу этот принятый ответ как ответ на заданный вопрос. Не могли бы вы дать какое-нибудь объяснение? Как то, что c_colorrr, c_onEnterrr (), c_onLeaveeee делают в этом конкретном фрагменте кода?
luqo33
1
Это значит, что при вводе мыши нужно изменить цвет на синий, а при выходе из мыши - желтый.
Михал Зиобро
Где вы размещаете директиву в разметке? Кажется, вы поместите его в тег body, но это будет за пределами корневого компонента. Если вас смущает этот ответ, эта ссылка может помочь ng2.codecraft.tv/custom-directives/hostlistener-and-hostbinding
mtpultz
@mtpultz Это в классе.
Серкан
33

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

@HostBinding('class.fixed-thing')
@Input()
fixed: boolean;
Альтшулер
источник
1
Можете ли вы поделиться примером использования @Input()?
Мано
Пример прямо в моем ответе, вы просто пишете оба декоратора один за другим, порядок не должен иметь значения
altschuler
1
Я думаю, что мне не хватает, как это отличается от просто использования @HostBinding. Когда вам нужно использовать @Input?
1252748
11

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

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

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

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

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

Готово
источник
9

Резюме:

  • @HostBinding: Этот декоратор связывает свойство класса со свойством элемента host.
  • @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';
  }

}

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

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

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

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

<p p_Dir>some paragraph</p>

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

Виллем ван дер Веен
источник
6

Теория с меньшим количеством жаргонов

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

пример

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

И там, где необходимо знать, какое действие на самом деле было выполнено пользователем, в которое входит @Hostlistening

Ralphkay
источник
3
Это сбивает с толку, а имена декораторов неточны.
Матманчини