Динамически добавить прослушиватель событий в Angular 2

Утро все, Я только начинаю возиться с Angular 2, и мне интересно, может ли кто-нибудь сказать мне лучший способ динамически добавлять и удалять прослушиватели событий из элементов.

У меня есть компонент. Когда щелкнут какой-либо элемент в шаблоне, я хочу добавить слушателя для mousemove к другому элементу того же шаблона. Затем я хочу удалить этот прослушиватель, когда нажат третий элемент.

Я как-то получил эту работу, просто используя простой Javascript, чтобы захватить элементы, а затем вызвал стандартный addEventListener(), но я подумал, существует ли более "Angular2.0" способ сделать это, что я должен смотреть в.

Приветствия за любой совет:)

Ответ 1

Renderer устарел в Angular 4.0.0-rc.1, прочитайте обновление ниже

Способ angular2 - использовать listen или listenGlobal из Renderer

Например, если вы хотите добавить событие Click к компоненту, вы должны использовать Renderer и ElementRef (это дает вам также возможность использовать ViewChild или все, что извлекает nativeElement)

constructor(elementRef: ElementRef, renderer: Renderer) {

    // Listen to click events in the component
    renderer.listen(elementRef.nativeElement, 'click', (event) => {
      // Do something with 'event'
    })
);

Вы можете использовать listenGlobal, который даст вам доступ к document, body и т.д.

renderer.listenGlobal('document', 'click', (event) => {
  // Do something with 'event'
});

Обратите внимание, что с момента бета2 оба listen и listenGlobal возвращают функцию для удаления слушателя (см. нарушение изменений из списка изменений для бета2). Это делается для того, чтобы избежать утечек памяти в больших приложениях (см. # 6686).

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

// listenFunc will hold the function returned by "renderer.listen"
listenFunc: Function;

// globalListenFunc will hold the function returned by "renderer.listenGlobal"
globalListenFunc: Function;

constructor(elementRef: ElementRef, renderer: Renderer) {

    // We cache the function "listen" returns
    this.listenFunc = renderer.listen(elementRef.nativeElement, 'click', (event) => {
        // Do something with 'event'
    });

    // We cache the function "listenGlobal" returns
    this.globalListenFunc = renderer.listenGlobal('document', 'click', (event) => {
        // Do something with 'event'
    });
}

ngOnDestroy() {
    // We execute both functions to remove the respectives listeners

    // Removes "listen" listener
    this.listenFunc();

    // Removs "listenGlobal" listener
    this.globalListenFunc();
}

Здесь plnkr с примером работы. Пример содержит использование listen и listenGlobal.

Использование RendererV2 с Angular 4.0.0-rc.1 + (Renderer2 с 4.0.0-rc.3)

  • 25/02/2017: Renderer устарел, теперь мы должны использовать RendererV2 (см. строку ниже). См. commit.

  • 10/03/2017: RendererV2 был переименован в Renderer2. См. нарушение изменений.

RendererV2 не имеет функции listenGlobal для глобальных событий (документ, тело, окно). Он имеет только функцию listen, которая обеспечивает обе функции.

Для справки, я копирую и вставляю исходный код реализации DOM Renderer, поскольку он может измениться (да, это angular!).

listen(target: 'window'|'document'|'body'|any, event: string, callback: (event: any) => boolean):
      () => void {
    if (typeof target === 'string') {
      return <() => void>this.eventManager.addGlobalEventListener(
          target, event, decoratePreventDefault(callback));
    }
    return <() => void>this.eventManager.addEventListener(
               target, event, decoratePreventDefault(callback)) as() => void;
  }

Как вы можете видеть, теперь он проверяет, передаем ли мы строку (документ, тело или окно), и в этом случае она будет использовать внутреннюю функцию addGlobalEventListener. В любом другом случае, когда мы передаем элемент (nativeElement), он будет использовать простой addEventListener

Чтобы удалить слушателя так же, как и с Renderer в Angular 2.x. listen возвращает функцию, затем вызывает эту функцию.

Пример

// Add listeners
let global = this.renderer.listen('document', 'click', (evt) => {
  console.log('Clicking the document', evt);
})

let simple = this.renderer.listen(this.myButton.nativeElement, 'click', (evt) => {
  console.log('Clicking the button', evt);
});

// Remove listeners
global();
simple();

plnkr с Angular 4.0.0-rc.1, используя RendererV2

plnkr с Angular 4.0.0-rc.3, используя Renderer2