javascript - 回调在 Angular2/Firebase 中生成 "TypeError: this is undefined"

标签 javascript typescript firebase angular

我试图了解这里发生了什么,以及为什么如果我以某种方式调用函数时会出现错误,而当我以不同的方式调用函数时却不会出现错误。这是首先产生错误的方式:

player.service.ts file

@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 file

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

call non-working version like this

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

错误:

EXCEPTION: TypeError: this is undefined

Working version

像这样工作正常,但没有使用 setInterval() 因为 activateTimer 只是调用服务方法

room.component.ts file

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

call working version like this

activateTimer(room.id, room.name)

为什么当我调用 postGameActions 作为回调时,'this' 未定义?我确定我在这里遗漏了一些简单的东西

最佳答案

您需要将调用包装到箭头函数中:

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

您的代码中的问题是您直接引用了一个函数,因此您丢失了它将在其上执行的对象。

另一种方法是使用绑定(bind)方法:

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

关于javascript - 回调在 Angular2/Firebase 中生成 "TypeError: this is undefined",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36815028/

相关文章:

typescript - 在 Typescript 中,当数组包含不同的元素类型时,如何从数组类型中获取元素类型?

javascript - 我如何重构我的方法?

javascript - 如何向 Cloud Firestore 中的对象添加新属性

firebase - 将数据添加到 Firebase ID token

javascript - 用于重置下拉菜单的单独按钮

javascript - 解析作为响应返回的 JSON 对象

angularjs - Restangular错误拦截器-如何将自定义对象传递给不了解restangular的 Controller ?

ios - 在Swift中使用segue传递Firestore的documentID

javascript - 正则表达式接受字符串前后的空格

javascript - 如何在变量中获取 ClientID