动态添加事件监听器 [英] Dynamically add event listener

查看:308
本文介绍了动态添加事件监听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用Angular 2,我想知道是否有人可以告诉我从元素动态添加和删除事件侦听器的最佳方法。

I am just starting to mess around with Angular 2 and I wonder if anyone can tell me the best way to dynamically add and remove event listeners from elements.

I有一个组件设置。单击模板中的某个元素时,我想将 mousemove 的侦听器添加到同一模板的另一个元素中。然后,我想在单击第三个元素时删除该侦听器。

I have a component set up. When a certain element in the template is clicked I want to add a listener for mousemove to another element of the same template. I then want to remove this listener when a third element is clicked.

我有点用普通的Javascript抓取元素然后调用标准的 addEventListener(),但我想知道是否还有一种我应该研究的 Angular2.0 方法。

I kind of got this working just using plain Javascript to grab the elements and then calling the standard addEventListener() but I wondered if there was a more "Angular2.0" way of doing this that I should be looking into.

推荐答案

Renderer已在Angular 4.0.0-rc.1中弃用,请阅读以下更新



angular2方式是使用 listen listenGlobal 来自渲染器

例如,如果要向组件添加click事件,则必须使用Renderer和ElementRef(这也使您可以选择使用ViewChild或检索 nativeElement

For example, if you want to add a click event to a Component, you have to use Renderer and ElementRef (this gives you as well the option to use ViewChild, or anything that retrieves the nativeElement)

constructor(elementRef: ElementRef, renderer: Renderer) {

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

您可以使用 listenGlobal 访问文档 body 等。

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

请注意,自beta.2以来,都收听 listenGlobal 返回删除监听器的函数(请参见更改更改部分)。这是为了避免大型应用程序中的内存泄漏(请参阅#6686 )。

Note that since beta.2 both listen and listenGlobal return a function to remove the listener (see breaking changes section from changelog for beta.2). This is to avoid memory leaks in big applications (see #6686).

因此,要删除动态添加的监听器,必须分配 listen listenGlobal 到将保存返回的函数的变量,然后我们执行它。

So to remove the listener we added dynamically we must assign listen or listenGlobal to a variable that will hold the function returned, and then we execute it.

// 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 的用法。

Here's a plnkr with an example working. The example contains the usage of listen and listenGlobal.


  • 2017年2月25日:已弃用 Renderer ,现在我们应该使用 RendererV2 (请参见下面的行)。参见提交

  • 25/02/2017: Renderer has been deprecated, now we should use RendererV2 (see line below). See the commit.

2017年3月10日 RendererV2 重命名为 Renderer2 。请参见重大更改

10/03/2017: RendererV2 was renamed to Renderer2. See the breaking changes.

RendererV2 没有 listenGlobal 函数用于全局事件(文档,正文,窗口)。它只有一个 listen 函数,可以同时实现这两个功能。

RendererV2 has no more listenGlobal function for global events (document, body, window). It only has a listen function which achieves both functionalities.

作为参考,我在这里复制&粘贴 DOM Renderer实现的源代码,因为它可能会更改(是的,这是有角度的!)。

For reference, I'm copy & pasting the source code of the DOM Renderer implementation since it may change (yes, it's 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

As you can see, now it verifies if we're passing a string (document, body or window), in which case it will use an internal addGlobalEventListener function. In any other case, when we pass an element (nativeElement) it will use a simple addEventListener

来删除监听器与在2.x中使用 Renderer 相同。 listen 返回一个函数,然后调用该函数。

To remove the listener it's the same as it was with Renderer in angular 2.x. listen returns a function, then call that function.

// 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

这篇关于动态添加事件监听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆