Angular2 компонент "this" - undefined при выполнении функции обратного вызова
У меня есть компонент, который вызывает службу для извлечения данных из конечной точки RESTful. Эта услуга должна быть предоставлена для функции обратного вызова после извлечения указанных данных.
Проблема заключается в том, что когда я пытаюсь использовать функцию обратного вызова для добавления данных к существующим данным в компонентной переменной, я получаю EXCEPTION: TypeError: Cannot read property 'messages' of undefined
. Почему this
undefined?
TypeScript версия: версия 1.8.10
Код контроллера:
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
})
}
}
Ответы
Ответ 1
Используйте функцию Function.prototype.bind:
getMessages() {
this.apiService.getMessages(this.gotMessages.bind(this));
}
Что происходит, так это то, что вы передаете gotMessages
в качестве обратного вызова, когда это выполняется, область действия различна, поэтому this
не то, что вы ожидали.
Функция bind
возвращает новую функцию, привязанную к this
, которую вы определили.
Вы можете, конечно, также использовать функцию толстой стрелки:
getMessages() {
this.apiService.getMessages(messages => this.gotMessages(messages));
}
Я предпочитаю синтаксис bind
, но это зависит от вас.
Третий вариант, чтобы связать метод для начала:
export class MainComponent {
getMessages = () => {
...
}
}
Ответ 2
Поскольку вы просто передаете ссылку функции в getMessages
, у вас нет правильного контекста this
.
Вы можете легко исправить это, используя лямбда, которая автоматически связывает правильный контекст this
для использования внутри этой анонимной функции:
getMessages(){
this.apiService.getMessages((data) => this.gotMessages(data));
}
Ответ 3
Или вы можете сделать это так:
gotMessages(messagesFromApi){
let that = this // somebody uses self
messagesFromApi.forEach((m) => {
that.messages.push(m) // or self.messages.push(m) - if you used self
})
}
Ответ 4
Пожалуйста, определите функцию
gotMessages = (messagesFromApi) => {
messagesFromApi.forEach((m) => {
this.messages.push(m)
})
}