Mam komponent, który wywołuje usługę do pobierania danych z punktu końcowego RESTful. Ta usługa musi otrzymać funkcję zwrotną do wykonania po pobraniu wspomnianych danych.
Problem polega na tym, że gdy próbuję użyć funkcji wywołania zwrotnego, aby dołączyć dane do istniejących danych w zmiennej składnika, otrzymuję plik EXCEPTION: TypeError: Cannot read property 'messages' of undefined
. Dlaczego jest this
nieokreślony?
Wersja TypeScript: Wersja 1.8.10
Kod kontrolera:
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
})
}
}
javascript
arrays
typescript
angular
Michael Gradek
źródło
źródło
tsc -v
)Odpowiedzi:
Użyj funkcji Function.prototype.bind :
getMessages() { this.apiService.getMessages(this.gotMessages.bind(this)); }
To, co się tutaj dzieje, to to, że przekazujesz
gotMessages
wywołanie zwrotne jako wywołanie zwrotne, gdy jest ono wykonywane, zakres jest inny, więcthis
nie jest to, czego oczekiwałeś. Funkcja zwraca nową funkcję, która jest związana z zdefiniowano.bind
this
Możesz oczywiście użyć tam również funkcji strzałek :
getMessages() { this.apiService.getMessages(messages => this.gotMessages(messages)); }
Wolę
bind
składnię, ale to zależy od Ciebie.Trzecia opcja, aby powiązać metodę na początek:
export class MainComponent { getMessages = () => { ... } }
Lub
export class MainComponent { ... constructor(private apiService: ApiService) { this.getMessages = this.getMessages.bind(this); } getMessages(){ this.apiService.getMessages(gotMessages); } }
źródło
Lub możesz to zrobić w ten sposób
gotMessages(messagesFromApi){ let that = this // somebody uses self messagesFromApi.forEach((m) => { that.messages.push(m) // or self.messages.push(m) - if you used self }) }
źródło
Ponieważ po prostu przekazujesz odwołanie do funkcji
getMessages
, nie masz odpowiedniegothis
kontekstu.Możesz to łatwo naprawić, używając lambdy, która automatycznie wiąże odpowiedni
this
kontekst do użycia w tej anonimowej funkcji:getMessages(){ this.apiService.getMessages((data) => this.gotMessages(data)); }
źródło
Mam ten sam problem, rozwiązany za pomocą () => {} zamiast funkcji ()
źródło
Określ funkcję
gotMessages = (messagesFromApi) => { messagesFromApi.forEach((m) => { this.messages.push(m) }) }
źródło