2016-07-07 59 views
34

我有一个组件调用服务以从RESTful端点获取数据。在获取所述数据之后,需要给这个服务一个回调函数来执行。执行回调函数时,Angular2组件的“this”未定义

问题是,当我尝试使用回调函数将数据附加到组件变量中的现有数据时,我得到一个EXCEPTION: TypeError: Cannot read property 'messages' of undefined。为什么this未定义?

打字稿版本:版本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

您正在使用哪种版本的TypeScript? (你可以用'tsc -v'来检查) – rinukkusu

+0

因为forEach而异常。改用For-of。 –

回答

71

使用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 =() => { 
     ... 
    } 
} 
+0

工作过,谢谢!并感谢解释为什么会发生这种情况。 –

+0

保存我的时间....好解释 –

7

因为你只是传递getMessages函数引用你没有正确的this上下文。

您可以轻松地解决这个问题,通过使用一个lambda自动绑定正确的this上下文匿名函数内部使用:

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

就是这样!谢谢 –

0

请定义功能

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

或者你也可以做到这一点像这样

gotMessages(messagesFromApi){ 
    let that = this // somebody uses self 
    messagesFromApi.forEach((m) => { 
     that.messages.push(m) // or self.messages.push(m) - if you used self 
    }) 
} 
相关问题