कॉलबैक फ़ंक्शन को निष्पादित करते समय Angular2 घटक का "यह" अपरिभाषित है


94

मेरे पास एक घटक है जो एक सेवा को RESTful समापन बिंदु से डेटा लाने के लिए कहता है। इस सेवा को डेटा कहा जाने के बाद निष्पादित करने के लिए कॉलबैक फ़ंक्शन देने की आवश्यकता है।

समस्या यह है कि जब मैं किसी घटक के चर में मौजूदा डेटा को डेटा को जोड़ने के लिए कॉलबैक फ़ंक्शन का उपयोग करने का प्रयास करता हूं, तो मुझे ए मिलता है EXCEPTION: TypeError: Cannot read property 'messages' of undefinedthisअपरिभाषित क्यों है ?

टाइपस्क्रिप्ट संस्करण: संस्करण 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
        })
    }
}

टाइपस्क्रिप्ट के किस संस्करण का आप उपयोग कर रहे हैं? (आप उस के साथ जाँच कर सकते हैं tsc -v)
rinukkusu

अपवाद क्योंकि forEach। इसके बजाय का उपयोग करें।
पैक्स बीच

जवाबों:


158

फ़ंक्शन.प्रोटोटाइप.बिंद फ़ंक्शन का उपयोग करें :

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

यहां क्या होता है कि आप gotMessagesकॉलबैक के रूप में पास करते हैं , जब उस पर अमल किया जा रहा है तो गुंजाइश अलग होती है और यही thisवह नहीं है जिसकी आपको उम्मीद थी। समारोह एक नया समारोह है कि के लिए बाध्य है देता है आप को परिभाषित किया।
bindthis

आप निश्चित रूप से, वहाँ एक तीर समारोह का उपयोग कर सकते हैं :

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
काम किया, धन्यवाद! और यह समझाने के लिए धन्यवाद कि ऐसा क्यों होता है।
माइकल ग्रैडेक

धन्यवाद! तथ्य यह है कि OOP- शैली जावास्क्रिप्ट विशिष्टता लीक कर रहा है (बाइंड) दुखद है।
skfd

21

या आप इसे इस तरह से कर सकते हैं

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

13

क्योंकि आप केवल फ़ंक्शन संदर्भ को पास कर रहे हैं, getMessagesआपके पास सही thisसंदर्भ नहीं है ।

आप आसानी से एक लंबो का उपयोग करके ठीक कर सकते हैं जो स्वचालित रूप से thisउस अनाम फ़ंक्शन के अंदर उपयोग के लिए सही संदर्भ को बांधता है :

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

वह यह था! धन्यवाद
बजे माइकल ग्रैडक जुएल

उत्तम। सबसे सरल और कुशल उपाय।
कोन

1

मेरे पास एक ही मुद्दा है, () => {} के बजाय फ़ंक्शन () का उपयोग करके हल किया गया


यह मौजूदा उत्तरों में कोई जानकारी नहीं जोड़ता है
DerMike

0

कृपया फ़ंक्शन को परिभाषित करें

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

यह मौजूदा उत्तरों में कोई जानकारी नहीं जोड़ता है
DerMike
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.