113 votes

Le composant "this" du composant Angular2 n'est pas défini lors de l'exécution de la fonction de rappel

J'ai un composant qui appelle un service pour extraire des données d'un noeud final RESTful. Ce service doit recevoir une fonction de rappel à exécuter après la récupération desdites données.

Le problème est que lorsque j'essaie d'utiliser la fonction de rappel pour ajouter les données aux données existantes dans la variable d'un composant, j'obtiens un EXCEPTION: TypeError: Cannot read property 'messages' of undefined . Pourquoi this indéfini?

Version TypeScript: Version 1.8.10

Code du contrôleur:

 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
        })
    }
}
 

206voto

Nitzan Tomer Points 11798

Utilisation de la Fonction.le prototype.lier la fonction:

getMessages() {
    this.apiService.getMessages(this.gotMessages.bind(this));
}

Ce qui se passe ici est que vous passez l' gotMessages rappel, lorsque que l'exécution de la portée est différente, et l' this n'est pas ce que vous attendiez.
L' bind fonction renvoie une nouvelle fonction qui est lié à l' this que vous avez défini.

Vous pouvez, bien sûr, utiliser une flèche de la fonction y ainsi:

getMessages() {
    this.apiService.getMessages(messages => this.gotMessages(messages));
}

Je préfère l' bind de la syntaxe, mais c'est à vous.

Une troisième option, afin de lier la méthode pour commencer:

export class MainComponent {
    getMessages = () => {
        ...
    }
}

Ou

export class MainComponent {
    ...

    constructor(private apiService: ApiService) {
        this.getMessages = this.getMessages.bind(this);
    }

    getMessages(){
        this.apiService.getMessages(gotMessages);
    }
}

21voto

Michal Kliment Points 196

Ou tu peux le faire comme ça

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

18voto

rinukkusu Points 14217

Parce que vous ne faites que passer la référence de la fonction dans getMessages vous n'avez pas le bon contexte this .

Vous pouvez facilement résoudre ce problème en utilisant un lambda qui lie automatiquement le bon contexte this pour l'utilisation à l'intérieur de cette fonction anonyme:

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

0voto

Tài Points 1

S'il vous plaît définir la fonction

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X