我有一个组件调用服务从RESTful端点获取数据。需要为此服务提供一个回调函数,以便在获取所述数据后执行。
问题是当我尝试使用回调函数将数据附加到组件变量中的现有数据时,我得到EXCEPTION: TypeError: Cannot read property 'messages' of undefined
。为什么this
未定义?
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
})
}
}
答案 0 :(得分:120)
getMessages() {
this.apiService.getMessages(this.gotMessages.bind(this));
}
这里发生的是您将gotMessages
作为回调传递,当执行该回调时,范围不同,因此this
不符合您的预期。
bind
函数返回一个绑定到您定义的this
的新函数。
当然,您也可以在那里使用arrow function:
getMessages() {
this.apiService.getMessages(messages => this.gotMessages(messages));
}
我更喜欢bind
语法,但这取决于你。
第三个选项,以便将方法绑定到以下开头:
export class MainComponent {
getMessages = () => {
...
}
}
或者
export class MainComponent {
...
constructor(private apiService: ApiService) {
this.getMessages = this.getMessages.bind(this);
}
getMessages(){
this.apiService.getMessages(gotMessages);
}
}
答案 1 :(得分:17)
或者你可以这样做
gotMessages(messagesFromApi){
let that = this // somebody uses self
messagesFromApi.forEach((m) => {
that.messages.push(m) // or self.messages.push(m) - if you used self
})
}
答案 2 :(得分:9)
因为您只是在getMessages
中传递了函数引用,所以您没有正确的this
上下文。
您可以使用lambda轻松解决这个问题,该lambda会自动绑定正确的this
上下文,以便在匿名函数中使用:
getMessages(){
this.apiService.getMessages((data) => this.gotMessages(data));
}
答案 3 :(得分:2)
我有同样的问题,可以使用()=> {}代替 function()
答案 4 :(得分:0)
请定义功能
gotMessages = (messagesFromApi) => {
messagesFromApi.forEach((m) => {
this.messages.push(m)
})
}