Прослушивание событий DOM и поддержание работоспособности приложения Angular может быть сложной задачей. Angular предлагает несколько методов для прослушивания событий. Изучая эти доступные варианты и методы, мы можем понять и знать характеристики, которые есть у каждого из них. В этой серии блогов будут рассмотрены четыре варианта прослушивания и реакции на события DOM:

  1. Привязка к событию: односторонняя привязка данных, при которой информация отправляется из шаблона компонента в класс компонента.
  2. @HostListener: декоратор Angular, который обрабатывает события в элементе хоста.
  3. Renderer2: использование метода Renderer2 .listen() для целевого события и элемента.
  4. RxJS: использование оператора RxJS .fromEvent(), который превращает события в наблюдаемые последовательности.

Дай дураку молотком, и все станет гвоздем.

Нет такого инструмента, который работал бы во всех случаях использования. Прослушивание событий DOM ничем не отличается. В этой серии статей, когда мы будем углубляться в эти четыре варианта, имейте это в виду, потому что каждый из рассматриваемых нами методов имеет свои преимущества и недостатки. Но в этой записи блога давайте погрузимся в привязку событий Angular.

Привязка к событию

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

Таким образом, это самый простой способ прослушивания событий в элементах в шаблоне компонента. Давайте посмотрим на простой пример привязки событий:

 <button (click)="handleClick()">Save</button>

Как показано в приведенном выше примере, вы помещаете имя целевого события в скобки слева от знака равенства, а обработчик событий - в кавычки справа от знака равенства. Вы также можете привязать неограниченное количество обработчиков событий к одному и тому же событию, разделив их точкой с запятой:

<button (click)="handleClick1(); handleClick2(); …">Save</button>

Если вам нужен доступ к объекту полезной нагрузки события, вы можете передать $event в качестве аргумента вашей функции-обработчику:

<button (click)="handleClick($event)">Save</button>

Как и в примере выше, убедитесь, что он прошел точно так же, как "$event”. Angular распознает это и передает полезную нагрузку события, которая является собственным объектом события, испускаемым браузером. Если вы передадите его неправильно (например, отсутствует знак $), вы получите undefined в своей функции-обработчике. Если вам нужно что-то конкретное от объекта полезной нагрузки, вы можете передать это непосредственно в функцию-обработчик с одним из свойств события:

<button (click)="handleClick($event.target)">Save</button>

Есть еще одна особенность событий Angular в отношении событий keyup и keydown. Если вам нужно только прослушивать определенные клавиши, Angular предлагает для этого ярлыки. Например, чтобы прослушивать только клавишу ENTER, вы можете указать эту клавишу как свойство событий keyup или keydown: keyup.enter или keydown.enter. Эти конкретные ключевые события называются псевдособытиями. Вы можете использовать псевдособытия с привязкой к событию:

<input (keydown.enter)="onEnterKey($event)">

Мы даже можем послушать комбинации клавиш:

<input (keyup.control.shift.enter)="onCtrlShiftEnter($event)">

Вы можете видеть, насколько легко Angular позволяет прослушивать сложные комбинации клавиш. Однако в настоящее время в Angular отсутствует подробная документация по псевдособытиям. Итак, я написал еще один краткий пост в блоге на тему Псевдо-события Angular.

А как насчет ограничений в привязке событий? Что ж, есть некоторые ограничения, связанные с шаблоном компонента. Это означает, что вы не можете прослушивать события, запущенные вне шаблона компонентов. Еще одно ограничение для привязки событий заключается в том, что вы не можете прослушивать события в элементе хоста вашего компонента, который является оболочкой для шаблона компонента. В следующем посте этой серии я расскажу о @HostListener, который позволяет вам прослушивать события на самом хосте.

Но у каждого правила есть исключения. Даже если вы не можете прослушивать события вне шаблона компонента, вы можете прослушивать события в глобальных элементах, таких как window, document и body, с привязкой к событию.

<button (document:click)="handleClick()">Save</button>

В этом примере функция "handleClick()" реагирует на нажатие как кнопки, так и всего документа. Однако прослушивание событий в глобальных элементах, таких как окно или документ, не рекомендуется, поскольку это ограничивает возможность повторного использования самих компонентов. Если у вас есть несколько экземпляров компонента, который обрабатывает одно из глобальных событий , тогда все экземпляры будут одновременно пытаться ответить на событие после его запуска. Это напрямую влияет на производительность ваших компонентов и приложения в целом.

Что-то еще, что может обрабатывать обычная привязка событий Angular, - это события, которые передаются родительскому компоненту из дочернего компонента. Если событие DOM запускается в дочернем элементе, родительский компонент будет слышать его, когда событие распространяется вверх. Следует отметить, что так всплывают только события DOM. Пользовательские события Angular, запускаемые EventEmitter , не всплывают. Также имейте в виду, что пользовательские события Angular отличаются от пользовательских событий DOM, которые всплывают, как обычные события DOM.

Наконец, последнее, что следует отметить в отношении привязки событий, - это то, что вы не можете динамически добавлять или удалять прослушиватель после того, как привязка события установлена ​​для элемента в шаблоне компонента. Привязки будут активны после рендеринга элемента в DOM и останутся активными до тех пор, пока он не будет удален из DOM. Это означает, что для привязки событий именно Angular управляет запуском или прекращением прослушивания слушателем своих целевых событий. Позже в этой серии мы рассмотрим использование Renderer2 и RxJS для динамического добавления и удаления прослушивателей событий только при соблюдении определенных условий. Это позволит нам создавать компоненты и директивы, которые обрабатывают события и управляют ими сложными способами.

Подведем итоги - основные выводы:

  • Связывание событий - это самый простой (или наиболее подходящий) способ прослушивания событий в шаблоне компонента.
  • При привязке событий вы не можете прослушивать события, инициированные вне шаблона компонента, за исключением глобальных элементов, таких как window, document и body.
  • Прослушивание глобальных событий в повторно используемом компоненте не рекомендуется, поскольку это потенциально может привести к снижению производительности.
  • Родительский компонент может слышать и улавливать события DOM (а не пользовательские события Angular), запускаемые внутри дочерних компонентов, когда события всплывают.
  • Привязки событий будут активны после того, как они будут установлены для элемента, и они будут оставаться активными до тех пор, пока элементы не будут удалены из DOM, что означает, что вы не можете контролировать, когда добавлять или удалять прослушиватели событий динамически.

Следите за новостями в блоге о слушателях событий, пока я исследую другие методы прослушивания событий DOM в Angular.