Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 动态添加事件侦听器_Angular_Typescript_Addeventlistener - Fatal编程技术网

Angular 动态添加事件侦听器

Angular 动态添加事件侦听器,angular,typescript,addeventlistener,Angular,Typescript,Addeventlistener,我刚开始搞Angular 2,我想知道是否有人能告诉我从元素中动态添加和删除事件侦听器的最佳方法 我设置了一个组件。单击模板中的某个元素时,我想将mousemove的侦听器添加到同一模板的另一个元素中。然后,我想在单击第三个元素时删除此侦听器 我只是使用普通Javascript获取元素,然后调用标准的addEventListener()就可以实现这一点,但我想知道是否有一种更“Angular2.0”的方法,我应该研究一下。渲染器在Angular 4.0.0-rc.1中被弃用,请阅读下面的更新 a

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

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

我只是使用普通Javascript获取元素,然后调用标准的
addEventListener()
就可以实现这一点,但我想知道是否有一种更“Angular2.0”的方法,我应该研究一下。

渲染器在Angular 4.0.0-rc.1中被弃用,请阅读下面的更新 angular2方法是使用
listen
listenGlobal
from

例如,如果要向组件添加单击事件,则必须使用Renderer和ElementRef(这也为您提供了使用ViewChild或任何检索
nativeElement
的选项)

构造函数(elementRef:elementRef,renderer:renderer){
//侦听组件中的单击事件
renderer.listen(elementRef.nativeElement,'单击',(事件)=>{
//用“事件”做点什么
})
);
您可以使用
listenGlobal
来访问
文档
正文

renderer.listenGlobal('document','click',(event)=>{
//用“事件”做点什么
});
请注意,自beta.2以来,
listen
listenGlobal
都返回一个函数来删除侦听器(请参阅beta.2的changelog部分)。这是为了避免大型应用程序中的内存泄漏(请参阅)

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

//listenFunc将保存“renderer.listen”返回的函数
listenFunc:函数;
//globalListenFunc将保留“renderer.listenGlobal”返回的函数
globalListenFunc:函数;
构造函数(elementRef:elementRef,渲染器:渲染器){
//我们缓存函数“listen”返回
this.listenFunc=renderer.listen(elementRef.nativeElement,'click',(event)=>{
//用“事件”做点什么
});
//我们缓存函数“listenGlobal”返回的值
this.globalListenFunc=renderer.listenGlobal('document','click',(event)=>{
//用“事件”做点什么
});
}
恩贡德斯特罗(){
//我们执行这两个函数来删除respectives侦听器
//删除“侦听”侦听器
this.listenFunc();
//Removs“listenGlobal”侦听器
this.globalListenFunc();
}
下面是一个示例。该示例包含
listen
listenGlobal
的用法

使用带有角度4.0.0-rc.1+的RenderV2(从4.0.0-rc.3开始使用RenderR2)
  • 2017年2月25日
    渲染器
    已被弃用,现在我们应该使用
    renderv2
    (请参见下面的行)。请参阅

  • 2017年3月10日
    renderv2
    已重命名为
    renderr2
    。请参阅

不再具有全局事件(文档、正文、窗口)的
listenGlobal
功能。它只有一个
listen
功能,可以实现这两种功能

作为参考,我正在复制和粘贴DOM渲染器实现的,因为它可能会更改(是的,它是角度的!)

listen(目标:“窗口”|“文档”|“正文”|任意,事件:字符串,回调:(事件:任意)=>boolean):
()=>无效{
如果(目标类型=='string'){
返回void>this.eventManager.addGlobalEventListener(
目标、事件、事件默认值(回调);
}
返回void>this.eventManager.addEventListener(
target、event、decoratePreventDefault(回调))as()=>void;
}
如您所见,现在它验证我们是否正在传递字符串(文档、正文或窗口),在这种情况下,它将使用内部
addGlobalEventListener
函数。在任何其他情况下,当我们传递元素(nativeElement)时,它将使用简单的
addEventListener

要删除侦听器,与angular 2.x中的
Renderer
相同。
listen
返回一个函数,然后调用该函数

例子
//添加侦听器
让global=this.renderer.listen('document','click',(evt)=>{
console.log('单击文档',evt);
})
让simple=this.renderer.listen(this.myButton.nativeElement,'click',(evt)=>{
console.log('单击按钮',evt);
});
//删除侦听器
全局();
简单();
使用渲染器v2


使用Angular 4.0.0-rc.3使用渲染器2

我会发现这非常令人困惑。 正如@EricMartinez指出的,renderr2 listen()返回删除侦听器的函数:

ƒ(){return element.removeEventListener(eventName,/**@type{?}*/(handler),false);}
如果我正在添加一个侦听器

this.listenToClick=this.renderer.listen('document','click',(evt)=>{
警报(“单击文档”);
})
我希望我的函数执行我想要的,而不是完全相反的,即删除侦听器

//我预期会出现警报(“单击文档”);
这个.listenToClick();
//你实际上得到的是删除侦听器,所以没有什么。。。
在给定的场景中,将其命名为:

//添加侦听器
让unlistenGlobal=this.renderer.listen('document','click',(evt)=>{
console.log('单击文档',evt);
})
让removeSimple=this.renderer.listen(this.myButton.nativeElement,'click',(evt)=>{
console.log('单击按钮',evt);
});
好了
<commonlib-header
    [logo]="{ src: 'assets/img/logo.svg', alt: 'Logo', href: '#' }"
    [buttons]="[{ index: 0, innerHtml: 'Button', class: 'btn btn-primary', onClick: [serviceReference, 'stringFunctionName', ['arg1','arg2','arg3']] }]">
    </common-header>
export class HeaderComponent implements OnInit {

 _buttons: Array<NavItem> = []

 @Input()
  set buttons(buttons: Array<any>) {
    buttons.forEach(navItem => {
      let _navItem = new NavItem(navItem.href, navItem.innerHtml)

      _navItem.class = navItem.class

      _navItem.onClick = navItem.onClick // this is the array from the component @Input properties above

      this._buttons[navItem.index] = _navItem
    })
  }

  constructor() {}

  ngOnInit() {}

  onClick(fn: any){
    let ref = fn[0]
    let fnName = fn[1]
    let args = fn[2]

    ref[fnName].apply(ref, args)
  }
<div class="topbar-right">
  <button *ngFor="let btn of _buttons"
    class="{{ btn.class }}"
    (click)="onClick(btn.onClick)"
    [innerHTML]="btn.innerHtml | keepHtml"></button>
</div>
export class MyComponent implements OnInit, OnDestroy {

  public removeEventListener: () => void;

  constructor(
    private renderer: Renderer2, 
    private elementRef: ElementRef
  ) {
  }

  public ngOnInit() {
    this.removeEventListener = this.renderer.listen(this.elementRef.nativeElement, 'click', (event) => {
      if (event.target instanceof HTMLAnchorElement) {
        // Prevent opening anchors the default way
        event.preventDefault();
        // Your custom anchor click event handler
        this.handleAnchorClick(event);
      }
    });
  }

  public ngOnDestroy() {
    this.removeEventListener();
  }
}