首页 > 解决方案 > 如何以角度访问回调函数内的组件类变量?

问题描述

在我的组件中,我使用addEventListener传递的回调函数订阅了 html 点击事件。在回调函数中,我使用了这样的组件变量this.someVariable,但我看到 this 的范围已更改并设置为 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);
   }
}

标签: javascriptangulartypescriptdom-events

解决方案


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

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

解决方案 1 - ViewChild

在您的 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);
        ...
      })
    );
  }

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


推荐阅读