Как связать прослушиватель событий для отображаемых элементов в Angular 2?

Как я могу привязать прослушиватель событий к отображаемым элементам в Angular 2?

Я использую библиотеку перетаскивания Dragula. Он создает динамический HTML, но мое событие не привязано к динамическим элементам HTML.


person Sudhanshu sharma    schedule 12.01.2017    source источник
comment
Что такое визуализированные элементы или динамические элементы HTML. Пожалуйста, добавьте код, демонстрирующий, чего вы пытаетесь достичь.   -  person Günter Zöchbauer    schedule 12.01.2017


Ответы (5)


Чтобы добавить EventListener к элементу в angular 2+, мы можем использовать метод listen службы Renderer2 (Renderer устарел, поэтому используйте Renderer2):

listen(target: 'window'|'document'|'body'|any, eventName: string, callback: (event: any) =› boolean | void): () =› void

Пример:

export class ListenDemo implements AfterViewInit { 
   @ViewChild('testElement') 
   private testElement: ElementRef;
   globalInstance: any;       

   constructor(private renderer: Renderer2) {
   }

   ngAfterViewInit() {
       this.globalInstance = this.renderer.listen(this.testElement.nativeElement, 'click', () => {
           this.renderer.setStyle(this.testElement.nativeElement, 'color', 'green');
       });
    }
}

Примечание.

Когда вы используете этот метод для добавления прослушивателя событий к элементу в dom, вы должны удалить этот прослушиватель событий при уничтожении компонента

Вы можете сделать это следующим образом:

ngOnDestroy() {
  this.globalInstance();
}

Способ использования ElementRef в этом методе не должен подвергать ваше угловое приложение риску безопасности. подробнее об этом реферере в угрозе безопасности ElementRef angular 2

person HDJEMAI    schedule 04.11.2017
comment
Нужно ли «не слушать» onDestroy? Или Angular позаботится об этом? - person Wolf359; 02.04.2018
comment
@MehmetGunacti: Хороший вопрос. Ответ YES, и вы должны отменить прослушивание, когда вызывается ngOnDestroy. Я обновлю ответ этим. просто возьмите ссылку на this.renderer.listen как globalInstance=this.renderer.listen ... и вызовите ее после этого: ngOnDestroy() {this.globalInstance();} - person HDJEMAI; 05.04.2018
comment
@HDJEMAI Мне очень нравится этот ответ, но как добавить #testElement к отображаемому элементу, который находится вне нашего контроля? - person stack247; 12.04.2019

HostListener должен быть правильным способом привязки события к вашему компоненту:

@Component({
  selector: 'your-element'
})

export class YourElement {
  @HostListener('click', ['$event']) onClick(event) {
     console.log('component is clicked');
     console.log(event);
  }
}
person Hans Tiono    schedule 06.06.2018

Если вы хотите связать событие, такое как «щелчок», для всех элементов, имеющих один и тот же класс в отображаемом элементе DOM, вы можете настроить прослушиватель событий, используя следующие части кода в файле components.ts.

import { Component, OnInit, Renderer, ElementRef} from '@angular/core';

constructor( elementRef: ElementRef, renderer: Renderer) {
    dragulaService.drop.subscribe((value) => {
      this.onDrop(value.slice(1));
    });
}

public onDrop(args) {

  let [e, el] = args;

  this.toggleClassComTitle(e,'checked');

}


public toggleClassComTitle(el: any, name: string) {

    el.querySelectorAll('.com-item-title-anchor').forEach( function ( item ) {

      item.addEventListener('click', function(event) {
              console.log("item-clicked");

       });
    });

}
person Sagar Arora    schedule 12.01.2017

@HostListener('window:click', ['$event']) onClick(event){ }

проверьте эту ссылку ниже, чтобы обнаружить CapsLock при нажатии, нажатии и нажатии клавиши в текущем окне. Нет необходимости добавлять какое-либо событие в html-документ

Обнаружение и предупреждение пользователей о включенной блокировке прописных букв< /а>

person Gopala raja naika    schedule 02.04.2019

person    schedule
comment
Требуется ли ручная очистка (.removeEventListener()) после уничтожения компонента, или Angular позаботится об этом? - person kraftwer1; 03.02.2018
comment
Нет, если вы зарегистрируете его в обязательном порядке, вам нужно будет удалить его в обязательном порядке. - person Günter Zöchbauer; 03.02.2018
comment
Можем ли мы передать какие-либо аргументы вместе с bind? - person Kannan T; 16.09.2018
comment
@Kannan То, что вы передаете bind, будет доступно как this внутри onClick() { ... } при его вызове, так что да, практически любой объект может быть передан. - person Günter Zöchbauer; 19.09.2018
comment
Зачем нам нужно внедрять ElementRef в конструктор? Разве новая переменная не должна это делать? - person Henry; 05.06.2020
comment
Новая переменная — это только место для хранения значения, сама по себе она ничего не делает. Angular проверяет параметры конструктора классов, экземпляры которых он создает (все с @Component... @Injectable... или любыми другими его декораторами) и находит соответствующие значения в своем словаре инжектора, которые затем передает конструктору. - person Günter Zöchbauer; 05.06.2020
comment
Это небольшая точка, но, вероятно, поймать некоторые. Селектору, конечно, понадобится # или . в начале в зависимости от того, является ли это идентификатором или классом, например. '#my-element' если <div id="my-element"> - person Mike Poole; 11.06.2020
comment
Не забудьте добавить implements AfterViewInit в объявление класса - person tblev; 11.08.2020
comment
Кажется, я не могу удалить прослушиватели событий. Может ли кто-нибудь поделиться образцом того, как это можно сделать. В настоящее время у меня есть это: this.dropArea.addEventListener('dragleave', this.unHighlight.bind(this), false) и удалить this.dropArea.removeEventListener('dragleave', this.unHighlight.bind(this), false) - person Junaid; 25.06.2021
comment
Я предлагаю вам присвоить this.unHighlight.bind(this), false) переменной и использовать переменную для добавления и удаления, таким образом вы гарантируете, что добавляете и удаляете один и тот же экземпляр, в противном случае bind(), вероятно, возвращает другой (новый) экземпляр, а remove() думает, что вы пытаетесь удалить что-то, что никогда не добавлялся. - person Günter Zöchbauer; 25.06.2021