javascript - Angular-egenskaper blir odefinierade efter initialisering/onInit-funktioner
Jag har ett konstigt problem där egenskaper på en Angular-komponent jag har satt upp förlorar sina värden efter initialisering. Komponenten är bara en enkel HTML-fil med en videospelare på. (som nedan)
<video width="200" controls="true" poster="" id="video">
<source type="video/mp4" src="http://www.w3schools.com/html/mov_bbb.mp4">
</video>
Sedan i komponentens TypeScript-fil har jag försökt skapa egenskapen med ett fördefinierat värde, skapa den utan värde och sedan tilldela den i konstruktorn, och även skapa den utan värde och tilldela i onInit. I alla tre fallen kan jag se att den har rätt värde om jag loggar värdet i konsolen. Men i ett evenemang som kallas senare är värdet undefined. Egenskapen har inte heller bundits till några element eller något liknande.
Skapa egenskaper med värde
export class VideoPlayerComponent implements OnInit {
timeStarted = 0;
timePlayed = 0;
duration = 0;
video: HTMLVideoElement;
constructor() {
}
ngOnInit(): void {
//Have values when logged here
console.log("Time Started: " + this.timeStarted);
console.log("Time Played: " + this.timePlayed);
console.log("Duration: " + this.duration);
this.video = <HTMLVideoElement> document.getElementById("video");
this.video.addEventListener("pause", this.videoStoppedPlaying);
}
videoStoppedPlaying(event) {
//is undefined here
console.log("Time Started: " + this.timeStarted);
console.log("Time Played: " + this.timePlayed);
console.log("Duration: " + this.duration);
}
}
Skapa egenskaper och tilldela i konstruktorn
export class VideoPlayerComponent implements OnInit {
timeStarted: number;
timePlayed: number;
duration: number;
video: HTMLVideoElement;
constructor() {
this.timeStarted = 0;
this.timePlayed = 0;
this.duration = 0
this.video = <HTMLVideoElement> document.getElementById("video");
}
ngOnInit(): void {
//Have values when logged here
console.log("Time Started: " + this.timeStarted);
console.log("Time Played: " + this.timePlayed);
console.log("Duration: " + this.duration);
this.video.addEventListener("pause", this.videoStoppedPlaying);
}
videoStoppedPlaying(event) {
//is undefined here
console.log("Time Started: " + this.timeStarted);
console.log("Time Played: " + this.timePlayed);
console.log("Duration: " + this.duration);
}
}
Skapa egenskaper och tilldela dem i onInit
export class VideoPlayerComponent implements OnInit {
timeStarted: number;
timePlayed: number;
duration: number;
video: HTMLVideoElement;
constructor() {
}
ngOnInit(): void {
this.timeStarted = 0;
this.timePlayed = 0;
this.duration = 0
this.video = <HTMLVideoElement> document.getElementById("video");
//Have values when logged here
console.log("Time Started: " + this.timeStarted);
console.log("Time Played: " + this.timePlayed);
console.log("Duration: " + this.duration);
this.video.addEventListener("pause", this.videoStoppedPlaying);
}
videoStoppedPlaying(event) {
//is undefined here
console.log("Time Started: " + this.timeStarted);
console.log("Time Played: " + this.timePlayed);
console.log("Duration: " + this.duration);
}
}
Kan någon snälla ge någon insikt om vad som kan orsaka att värdet försvinner efter initialisering och laddning?
Svar #1
Detta beror på att nyckelordet this inte refererar till din komponent VideoPlayerComponent som du kanske tror, i ditt fall kommer det att referera till this.video.
På grund av följande kodrad:
this.video.addEventListener("pause", this.videoStoppedPlaying);
Funktionen videoStoppedPlaying anropas inom objektet video och som du kanske vet eller inte vet, refererar nyckelordet this till det objekt där det faktiskt anropas, vilket alltså refererar till video.
Inom video-objektet finns det ingen timeStarted och ingen timePlayed-egenskap och det är därför de är undefined, men det finns en egenskap som heter duration och det är därför du får ett värde för duration.
Om du vill veta mer om de egenskaper som finns inom video-objektet, kolla denna dokumentation och gå till HTML Audio/Video Properties.
Jag skapade också en live-demo för dig med en ytterligare egenskap.
Svar #2
du kan använda videons "händelse" för att få all data du behöver och tilldela den till de egenskaper du skapade
din VideostoppedPlaying-funktion kan se ut så här
videoStoppedPlaying(event) {
this.duration = event.target.duration
this.timePlayed = event.target.currentTime
console.log("Time Played: " + this.timePlayed);
console.log("Duration: " + this.duration);
}
}
Och glöm inte att lägga till "event" när du anropar funktionen vid addEventListener
this.video.addEventListener("pause",e=> this.videoStoppedPlaying(e));
