执行回调函数时,Angular2组件的“this”未定义

时间:2016-07-07 12:26:18

标签: javascript arrays typescript angular

我有一个组件调用服务从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
        })
    }
}

5 个答案:

答案 0 :(得分:120)

使用Function.prototype.bind功能:

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)
  })
}
相关问题