如何在 angular 中访问回调函数中的组件类变量?



在我的组件中,我使用addEventListener传递回调函数订阅了html单击事件。在回调函数中,我使用了像这样的组件变量this.someVariable,但我看到它的范围已被更改并设置为 html 元素对象。在这里如何使用组件变量?下面我给出了一个示例代码。在我的handleHtmlClickEvent()函数中,我无法访问this.x变量。

export class SomeComponent implements OnInit, AfterViewInit{
x = 'Hello';
constructor(private elementRef: ElementRef){}
ngOnInit(){
}
ngAfterViewInit(){
const element = this.elementRef.nativeElement.getByElementId('123');
element.addEventListener('click', this.handleHtmlClickEvent)
}
handleHtmlClickEvent(){
console.log(this.x);
}
}

不要直接触摸 DOM。这样做是一种不好的做法。

使用ViewChild装饰器或创建指令。

解决方案 1 - 查看子级

在 html 模板中,将模板变量分配给要定位的元素:

<div #element></div>

在组件中:

export class SomeComponent implements OnInit, AfterViewInit{
x = 'Hello';
@ViewChild('element') element: ElementRef<HTMLDivElement>;
// use @HostListener decorator to attach your listener
@HostListener('click', ['$event'])
onClick(event: MouseEvent) {
if (event.target === this.element.nativeElement) {
console.log(this.x);
}
}
}

解决方案 2 - 指令

@Directive({
selector: '[appSomeDirective]'
})
export class SomeDirective {
// use the Input decorator to display the message
@Input() message: string;
constructor(private elementRef: ElementRef){}
@HostListener('click', ["$event"])
onClick(event: MouseEvent) {
console.log(this.message);
}
}

在组件模板中:

<div appSomeDirective [message]="x"></div>

如果要操作一个或多个元素,请使用 Render2 服务。

更新

对于评论中描述的情况,您可以执行以下操作:

x = 'Hello';
@ViewChild('element') element: ElementRef<HTMLDivElement>;
constructor(private renderer: Renderer2) {}
ngAfterViewInit() {
const links = this.element.nativeElement.querySelectorAll('a');
links.forEach(link =>
// use the Renderer2 service to start an event listener 
this.renderer.listen(link, 'click', (event: MouseEvent) => {
console.log(this.x);
...
})
);
}

虽然上面的实现可以工作,但我不确定如果您有数十个或数百个链接,它的性能如何。

为点击事件分配范围

element.addEventListener('click', this.handleHtmlClickEvent.bind(this))

最新更新