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