Объем Javascript "это" в классе Typescript - PullRequest
2 голосов
/ 04 ноября 2019

Я пытаюсь изменить пользовательский значок видео, когда видео переключается (воспроизведение / пауза).

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 "function.

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')
});

Ответы [ 4 ]

2 голосов
/ 04 ноября 2019

Вы можете попробовать этот способ, используя 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);
}
2 голосов
/ 04 ноября 2019

Когда обработчик прослушивателя событий называется call, он не вызывается в области действия Компонента. Поэтому this возвращает не компонент, а элемент управления.

Вам необходимо привязать слушателя с помощью this.

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

См. Документ здесь .


Вы можете сделать это более понятным, разделив его на вызов функции onClick.

onClick() {
  this.updateVdoIcon(this);
}

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

Или вы можете захватить this в качестве компонента ипередать слушателю события.

let self = this;

vdo.addEventListener('play', function() {
      self.updateVdoIcon(this);
});
1 голос
/ 04 ноября 2019

Вот ваше решение

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: любой) {console.log (videoElment);// Ожидаем, что это будет элемент видео вместо класса машинописи}

1 голос
/ 04 ноября 2019

Вы можете передать event.currentTarget в обратном вызове, который будет вашим элементом, в котором вы определили прослушиватель событий:

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

В вашем фрагменте this будет лексический this в функции стрелки. Он захватывает контекст this из лексической области, то есть экземпляра класса.

...