簡體   English   中英

回調在Angular2 / Firebase中生成“TypeError:this is undefined”

[英]Callback generates “TypeError: this is undefined” in Angular2/Firebase

我試圖理解這里是什么鑼以及為什么我以某種方式調用函數而不是在我以不同的方式調用函數時得到錯誤時會出現錯誤。 以下是首先產生錯誤的方法:

player.service.ts文件

@Injectable我有

private roomsRef: Firebase;

constructor() {
    this.roomsRef   = new Firebase("https://xxx.firebaseio.com/rooms");
}

postGameActions(roomId: string) {
        console.log("post game actions start on " + roomId);

//error on below 'this'        
        this.roomsRef.child(roomId).child("board").once("value", snap => {
           let board = snap.val();
           //do stuff with 'board' object
        });
}

room.component.ts文件

activateTimer(roomId: string, roomName: string, callback) {
    var timer = setInterval(redirectTimer, 1000);
    var seconds: number = 5;
    var timerHtml = document.getElementById("divRedirectTimer" + roomName);
    timerHtml.innerHTML = "[" + seconds + "]";

    function redirectTimer() {
        timerHtml.innerHTML = "[" + (seconds--) + "]";
        if(seconds === 0) {
            clearInterval(timer);
            callback(roomId);
        }
    };
}

像這樣調用非工作版本

activateTimer(room.id, room.name, _playerService.postGameActions)

錯誤:

EXCEPTION: TypeError: this is undefined

工作版

這樣工作正常但沒有使用setInterval()因為activateTimer只調用服務方法

room.component.ts文件

activateTimer(roomId: string, roomName: string) {
    var timer = setInterval(redirectTimer, 1000);
    var seconds: number = 5;
    var timerHtml = document.getElementById("divRedirectTimer" + roomName);
    timerHtml.innerHTML = "[" + seconds + "]";

    function redirectTimer() {
        timerHtml.innerHTML = "[" + (seconds--) + "]";
        if(seconds === 0) {
            clearInterval(timer);
        }
    }

    this._playerService.postGameActions(roomId);

像這樣打電話的工作版

activateTimer(room.id, room.name)

當我將postGameActions稱為回調時,為什么'this'未定義? 我確定我在這里錯過了一些簡單的東西

您需要將調用包裝成箭頭函數:

activateTimer(room.id, room.name, () => {
  _playerService.postGameActions();
});

您的代碼中的問題是您直接引用一個函數,因此您將丟失它將在其上執行的對象。

另一種方法是使用bind方法:

activateTimer(room.id, room.name, _playerService.postGameActions.bind(_playerService);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM