2016-07-07 16 views
34

Mam składnik, który wywołuje usługę pobierania danych z punktu końcowego RESTful. Tej usłudze należy nadać funkcję zwrotną, która zostanie wykonana po pobraniu wspomnianych danych."To" składnika Angular2 jest niezdefiniowane podczas wykonywania funkcji wywołania zwrotnego.

Problem polega na tym, że próbuję użyć funkcji oddzwaniania w celu dołączenia danych do istniejących danych w zmiennej komponentu, otrzymuję numer EXCEPTION: TypeError: Cannot read property 'messages' of undefined. Dlaczego undefined jest this? Wersja

maszynopis: Wersja 1.8.10

kod Kontroler:

import {Component} from '@angular/core' 
import {ApiService} from '...' 

@Component({ 
    ... 
}) 
export class MainComponent { 

    private messages: Array<any>; 

    constructor(private apiService: ApiService){} 

    getMessages(){ 
     this.apiService.getMessages(gotMessages); 
    } 

    gotMessages(messagesFromApi){ 
     messagesFromApi.forEach((m) => { 
      this.messages.push(m) // EXCEPTION: TypeError: Cannot read property 'messages' of undefined 
     }) 
    } 
} 
+0

Którą wersję TypeScript używasz? (Możesz to sprawdzić za pomocą 'tsc -v') – rinukkusu

+0

Wyjątek, ponieważ forEach. Zamiast tego użyj For-of. –

Odpowiedz

71

Użyj Function.prototype.bind funkcja:

getMessages() { 
    this.apiService.getMessages(this.gotMessages.bind(this)); 
} 

Co się dzieje, jest to, że zdasz gotMessages jako zwrotnego, kiedy to jest wykonywane, zasięg jest inny, więc this nie jest tym, czego oczekiwałeś.
Funkcja bind zwraca nową funkcję, która jest przypisana do zdefiniowanej przez użytkownika this.

Można oczywiście użyć funkcji tłuszcz strzałki tam również:

getMessages() { 
    this.apiService.getMessages(messages => this.gotMessages(messages)); 
} 

Wolę składnię bind, ale to zależy od ciebie.

Trzecia opcja, tak aby powiązać metodę zacząć:

export class MainComponent { 
    getMessages =() => { 
     ... 
    } 
} 
+0

Pracowałem, dzięki! I dziękuję za wyjaśnienie, dlaczego tak się dzieje. –

+0

Zaoszczędziłem czas .... dobre wyjaśnienie –

7

bo jesteś tylko przejazdem odniesienie funkcji w getMessages nie masz odpowiedniego this kontekst.

można łatwo ustalić, że za pomocą lambda, która automatycznie wiąże właściwej this kontekst dla stosowania wewnątrz tej anonimowej funkcji:

getMessages(){ 
    this.apiService.getMessages((data) => this.gotMessages(data)); 
} 
+0

To było to! Dzięki –

0

Proszę funkcja definiowania

gotMessages = (messagesFromApi) => { 
    messagesFromApi.forEach((m) => { 
    this.messages.push(m) 
    }) 
} 
6

Albo można to zrobić lubisz to:

gotMessages(messagesFromApi){ 
    let that = this // somebody uses self 
    messagesFromApi.forEach((m) => { 
     that.messages.push(m) // or self.messages.push(m) - if you used self 
    }) 
} 
Powiązane problemy