2016-04-23 6 views
1

Ich versuche zu verstehen, was Gong hier ist und warum bekomme ich einen Fehler, wenn ich eine Funktion auf eine bestimmte Weise aufrufen und nicht den Fehler, wenn ich Rufen Sie die Funktion anders auf. Hier ist die Art und Weise, die den Fehler erzeugt zuerst:Callback generiert "TypeError: das ist undefined" in Angular2/Firebase

player.service.ts file

im @Injectable ich habe

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) 

Fehler:

EXCEPTION: TypeError: this is undefined 

Working version

funktioniert gut, wenn wie diese aber keinen Gebrauch von setInterval() seit activateTimer nur Anrufe der Service-Methode

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) 

Warum ist die 'this' nicht definiert, wenn ich rufe postGameActions als Rückruf? Ich bin sicher, ich bin etwas fehlt einfach hier

+0

Wie activateTimer genannt wird? –

Antwort

2

Sie müssen den Anruf in einen Pfeil Funktion wickeln:

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

Das Problem in Ihrem Code ist, dass man direkt eine Funktion verweisen, so dass Sie das Objekt verlieren es wird am ausgeführt werden.

Eine andere Möglichkeit wäre es, die bind-Methode zu verwenden:

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