回调在 Angular2/Firebase 中生成“TypeError:这是未定义的”

Posted

技术标签:

【中文标题】回调在 Angular2/Firebase 中生成“TypeError:这是未定义的”【英文标题】:Callback generates "TypeError: this is undefined" in Angular2/Firebase 【发布时间】:2016-08-17 08:04:11 【问题描述】:

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

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是怎么调用的? 【参考方案1】:

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

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

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

另一种方法是使用绑定方法:

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

【讨论】:

以上是关于回调在 Angular2/Firebase 中生成“TypeError:这是未定义的”的主要内容,如果未能解决你的问题,请参考以下文章

Dart/Flutter - 回调函数中的“yield”

来自 Java Runnable 的 Py4J 回调

提高CTP的jswig_JAVA接口回调线程处理效率

小程序中的支付以及回调

在python中生成密码

在本机反应中生成多个APK?