"This" komponentu Angular2 jest niezdefiniowany podczas wykonywania funkcji wywołania zwrotnego
Mam komponent, który wywołuje usługę w celu pobrania danych z RESTful endpoint. Ta usługa musi mieć funkcję wywołania zwrotnego do wykonania po pobraniu wspomnianych danych.
Problem polega na tym, że gdy próbuję użyć funkcji zwrotnej, aby dołączyć dane do istniejących danych w zmiennej komponentu, dostaję EXCEPTION: TypeError: Cannot read property 'messages' of undefined
. Dlaczego this
jest niezdefiniowany?
Wersja maszynopisu: 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
})
}
}
5 answers
Użyj funkcji .prototyp.funkcja bind:
getMessages() {
this.apiService.getMessages(this.gotMessages.bind(this));
}
Dzieje się tak, że przekazujesz gotMessages
jako wywołanie zwrotne, gdy jest ono wykonywane, zakres jest inny, więc this
nie jest tym, czego oczekiwałeś.
Funkcja bind
zwraca nową funkcję, która jest powiązana z this
, którą zdefiniowałeś.
Możesz oczywiście użyć funkcji strzałki również tam:
getMessages() {
this.apiService.getMessages(messages => this.gotMessages(messages));
}
Wolę składnię bind
, ale to zależy od Ciebie.
Trzecia opcja więc aby zwią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);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-30 08:10:24
Or you can do it like this
gotMessages(messagesFromApi){
let that = this // somebody uses self
messagesFromApi.forEach((m) => {
that.messages.push(m) // or self.messages.push(m) - if you used self
})
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-20 20:55:12
Ponieważ przekazujesz odwołanie do funkcji w {[1] } nie masz odpowiedniego kontekstu this
.
Można to łatwo naprawić, używając lambda, która automatycznie wiąże właściwy kontekst this
do użycia wewnątrz tej anonimowej funkcji:
getMessages(){
this.apiService.getMessages((data) => this.gotMessages(data));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-07 12:29:28
Mam ten sam problem, rozwiązany za pomocą () => { } instead function()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-12 10:44:53
Proszę zdefiniować funkcję
gotMessages = (messagesFromApi) => {
messagesFromApi.forEach((m) => {
this.messages.push(m)
})
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-15 02:34:15