【问题标题】:Javascript's scope "this" in Typescript's classTypescript 类中的 Javascript 范围“this”
【发布时间】:2019-11-04 14:37:28
【问题描述】:

当视频切换(播放/暂停)时,我正在尝试更改视频的自定义图标。

ngAfterViewInit() {
 const vdoCont = document.querySelector('.video-player');
 const vdo = vdoCont.querySelector('video');
    vdo.addEventListener('play', () => {
     console.log(this) // Here "this" refers to typescript class
     this.updateVdoIcon(this);
    });
    vdo.addEventListener('pause', () => {
     console.log(this) // Here "this" refers to typescript class
     this.updateVdoIcon(this);
    });
}

updateVdoIcon(videoElment: any) {
    console.log(videoElment); // Expecting this to be video element instead of typescript class
  }

我尝试将箭头函数更改为 JavaScript 函数,但在这里我无法使用我的“updateVdoIcon”函数。

vdo.addEventListener('play', function() {
      this.updateVdoIcon(this); // Property 'updateVdoIcon' does not exist on type 'HTMLVideoElement'
});

我知道我可以使用匿名函数(如下所示)并在此处更新图标,但是如果我有很多代码要在函数中分离,该怎么办

vdo.addEventListener('play', function() {
 this.paused ? console.log('Play icon') : console.log('Pause icon')
});

【问题讨论】:

    标签: javascript angular typescript this


    【解决方案1】:

    当事件监听处理函数被调用时,它不会在组件范围内被调用。所以this 不返回组件,而是返回控件元素。

    你需要用this绑定你的监听器。

    vdo.addEventListener('play', (function() {
          this.updateVdoIcon(this);
    }).bind(this));
    

    参见文档here


    您可以通过将其分离为 onClick 函数调用来使其更清晰。

    onClick() {
      this.updateVdoIcon(this);
    }
    
    initialize() {
      vdo.addEventListener('play', this.onClick.bind(this));
    }
    

    或者,您可以捕获this 作为组件并传递给事件监听器。

    let self = this;
    
    vdo.addEventListener('play', function() {
          self.updateVdoIcon(this);
    });
    

    【讨论】:

      【解决方案2】:

      你可以试试这种方式,使用ElementRef可以访问元素,然后绑定事件。

      源代码来自:https://stackoverflow.com/a/41610950/9380944 答案。

      import { AfterViewInit, Component, ElementRef} from '@angular/core';
      
      constructor(private elementRef:ElementRef) {}
      
      ngAfterViewInit() {
        this.elementRef.nativeElement.querySelector('my-element')
                                      .addEventListener('click', this.onClick.bind(this));
      }
      
      onClick(event) {
        console.log(event);
      }
      

      【讨论】:

        【解决方案3】:

        您可以在回调中传递event.currentTarget,这将是您定义事件侦听器的元素:

        vdo.addEventListener('play', (event) => {
             this.updateVdoIcon(event.currentTarget);
        });
        

        在您的 sn-p 中,this 将是箭头函数中的 词法 this。它从词法范围(即类实例)捕获this 上下文。

        【讨论】:

          【解决方案4】:

          这是你的解决方案

          ngAfterViewInit() {
          const vdoCont = document.querySelector('.video-player');
          const vdo = vdoCont.querySelector('video');
          const that = this;
             vdo.addEventListener('play', function(){
              console.log(this) // Here "this" refers to typescript class
              that.updateVdoIcon(this);
             });
             vdo.addEventListener('pause', function(){
              console.log(this) // Here "this" refers to typescript class
              that.updateVdoIcon(this);
             });
          

          }

          updateVdoIcon(videoElment: any) { console.log(videoElment); // 期望这是视频元素而不是 typescript 类 }

          【讨论】:

            猜你喜欢
            • 2013-07-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-12-22
            • 2013-06-20
            • 1970-01-01
            • 1970-01-01
            • 2013-02-24
            相关资源
            最近更新 更多