एक्सप्रेशनसंचालित इसके बाद ।हैसबैनचेक किए गए विवरण को समझाया


307

कृपया मुझे समझाएं कि मुझे यह त्रुटि क्यों हो रही है: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.

जाहिर है, मैं इसे केवल देव मोड में प्राप्त करता हूं, यह मेरे प्रोडक्शन बिल्ड पर नहीं होता है, लेकिन यह बहुत कष्टप्रद है और मैं अपने देव वातावरण में त्रुटि होने के लाभों को आसानी से नहीं समझता हूं, जो ठेस पर दिखाई नहीं देंगे - -क्योंकि मेरी समझ में कमी के कारण।

आमतौर पर, यह तय करना काफी आसान है, मैं इस तरह से सेटटाइमआउट में कोड के कारण त्रुटि को लपेटता हूं:

setTimeout(()=> {
    this.isLoading = true;
}, 0);

या इस तरह से एक कंस्ट्रक्टर के साथ परिवर्तनों का पता लगाने के लिए constructor(private cd: ChangeDetectorRef) {}:

this.isLoading = true;
this.cd.detectChanges();

लेकिन मैं लगातार इस त्रुटि में क्यों भागूं? मैं इसे समझना चाहता हूं ताकि मैं भविष्य में इन हैकी सुधारों से बच सकूं।


जवाबों:


121

मेरा मुद्दा भी ऐसा ही था। जीवन चक्र हुक प्रलेखन को देखते हुए , मैं बदल ngAfterViewInitगया ngAfterContentInitऔर यह काम किया।


@PhilipEnc मेरा मुद्दा DOM के परिवर्तन से शुरू हुए परिवर्तन से संबंधित था। जब DOM बदल जाएगा, QueryList ऑब्जेक्ट (जो @ContentChildren प्रॉपर्टी से आया था) अपडेट करेगा, और इस पद्धति के अंदर कि अद्यतन ने इसे दो-तरफ़ा बाउंड प्रॉपर्टी में बदल दिया। इससे मुझे जो समस्या हो रही थी, वह पैदा हुई। उस परिवर्तन को दो-गुण में बदल देना setTimeoutजैसे आपने ऊपर दिखाया है। धन्यवाद!
kbpontius

1
मेरे मामले में मैंने कुछ कोड रखे थे जो ngAfterContentInit में प्राइमेंग ग्रिड ऐरे के मूल्य को बदल दिया, मैंने कोड को ngOnInit में रखा और यह काम कर गया।
विभू

ngAfterContentCheckedयहाँ काम करता है जबकि ngAfterContentInitअभी भी त्रुटि फेंकता है।
ashubuntu

ngAfterContentChecked उपयोग लेकिन परियोजना बहुत धीमी गति से भरी हुई
घोटेकर राहुल

101

यह त्रुटि आपके आवेदन में एक वास्तविक समस्या को इंगित करती है, इसलिए यह अपवाद फेंकने के लिए समझ में आता है।

में devModeपरिवर्तन का पता लगाने अगर मॉडल बदल गया है की जाँच करने के लिए हर नियमित परिवर्तन का पता लगाने के चलने के बाद एक अतिरिक्त बारी कहते हैं।

यदि मॉडल नियमित और अतिरिक्त परिवर्तन का पता लगाने के बीच बदल गया है, तो यह इंगित करता है कि या तो

  • परिवर्तन का पता लगाने के कारण ही परिवर्तन हुआ है
  • एक विधि या गेट्टर हर बार एक अलग मूल्य देता है जिसे यह कहा जाता है

जो दोनों खराब हैं, क्योंकि यह स्पष्ट नहीं है कि कैसे आगे बढ़ना है क्योंकि मॉडल कभी भी स्थिर नहीं हो सकता है।

यदि मॉडल स्थिर होने तक कोणीय परिवर्तन का पता लगाता है, तो यह हमेशा के लिए चल सकता है। अगर कोणीय परिवर्तन का पता नहीं लगाता है, तो दृश्य मॉडल की वर्तमान स्थिति को प्रतिबिंबित नहीं कर सकता है।

यह भी देखें कि Angular2 में उत्पादन और विकास मोड में क्या अंतर है?


4
मैं भविष्य में इस त्रुटि को देखने से कैसे बच सकता हूं? क्या यह सुनिश्चित करने के लिए मेरे कोड के बारे में सोचने का एक अलग तरीका है कि मैं वही गलतियाँ न करूँ?
केविन लेस्टरगे

24
आम तौर पर इस तरह की कुछ जीवन चक्र कॉलबैक के कारण होता है ngOnInitया ngOnChangesमॉडल (कुछ जीवन चक्र कॉलबैक, मैं अपने आप को बिल्कुल याद नहीं है नहीं है जो कोई एक कार्य करें या नहीं मॉडल दूसरों को संशोधित अनुमति देते हैं) को संशोधित करने के लिए। दृश्य में विधियों या कार्यों के लिए बाध्य न करें, इसके बजाय फ़ील्ड से बाइंड करें और इवेंट हैंडलर में फ़ील्ड अपडेट करें। यदि आपको विधियों से बाध्य होना चाहिए, तो सुनिश्चित करें कि वे हमेशा उसी मान का रिटर्न देते हैं जब तक कि वास्तव में परिवर्तन नहीं हुआ था। चेंज डिटेक्शन इन तरीकों को बहुत बुलाएगा।
गुंटर ज़ोचबॉयर

यहां पहुंचने वाले किसी भी व्यक्ति के लिए जो एनएक्सएक्स-टोस्टर लाइब्रेरी का उपयोग करके इस त्रुटि को प्राप्त करता है, यहां बग रिपोर्ट है: github.com/scttcper/ngx-toastr/issues/160
rmcsharry

2
जरूरी नहीं कि यह ऐप की समस्या हो। तथ्य यह है कि कॉलिंग changeRef.detectChanges()एक समाधान है / त्रुटि को दबाता है, इस बात का प्रमाण है। यह राज्य के अंदर संशोधित करने की तरह है $scope.$watch()कोणीय 1 में
केविन बील

1
मैं Angular 1 को बहुत अच्छी तरह से नहीं जानता, लेकिन Angular 2 में परिवर्तन का पता लगाना काफी अलग तरह से काम करता है। आप सही हैं कि यह जरूरी नहीं कि एक समस्या है, लेकिन आमतौर cdRef.detectChanges()पर केवल कुछ अजीब धार वाले मामलों में ही आवश्यक होता है और आपको जरूरत पड़ने पर सावधानी से देखना चाहिए कि आप ठीक से समझ क्यों रहे हैं।
गुंटर ज़ोचबॉएर

83

एक बार जब मैं कोणीय जीवनचक्र के हुक और परिवर्तन का पता लगाने के साथ उनके संबंध को समझ गया तो बहुत कुछ समझ में आया ।

मैं *ngIfएक तत्व के लिए बाध्य वैश्विक ध्वज को अद्यतन करने के लिए कोणीय पाने की कोशिश कर रहा था , और मैं उस झंडे ngOnInit()को दूसरे घटक के जीवन चक्र हुक के अंदर बदलने की कोशिश कर रहा था ।

प्रलेखन के अनुसार, इस विधि को एंगुलर द्वारा पहले ही परिवर्तनों का पता लगाने के बाद कहा जाता है:

पहले ngOnChanges () के बाद एक बार कॉल किया जाता है।

इसलिए ध्वज को अपडेट करने से ngOnChanges()परिवर्तन का पता नहीं लगेगा। फिर, एक बार परिवर्तन का पता लगाने के बाद स्वाभाविक रूप से फिर से शुरू हो गया है, ध्वज का मूल्य बदल गया है और त्रुटि को फेंक दिया गया है।

मेरे मामले में, मैंने इसे बदल दिया:

constructor(private globalEventsService: GlobalEventsService) {

}

ngOnInit() {
    this.globalEventsService.showCheckoutHeader = true;
}

इसके लिए:

constructor(private globalEventsService: GlobalEventsService) {
    this.globalEventsService.showCheckoutHeader = true;
}

ngOnInit() {

}

और इसने समस्या तय कर दी :)


3
मेरी समस्या भी ऐसी ही थी। कि मैंने लंबे समय के बाद एक गलती की, और ngOnInit फ़ंक्शन और कंस्ट्रक्टर के बाहर एक चर को परिभाषित किया। यह एक नमूदार से डेटा परिवर्तन प्राप्त करता है, जिसे इनबिल्टेशन फ़ंक्शन में रखा जाता है। क्या आपने त्रुटि को ठीक करने के लिए ऐसा ही किया।
ravo10

1
चारों ओर बहुत समान है, लेकिन मैं router.navigateURL में मौजूद होने पर एक टुकड़े पर लोड करने ( ) को स्क्रॉल करने की कोशिश कर रहा था । यह कोड शुरू में रखा गया था AfterViewInitजहां मैं त्रुटि प्राप्त कर रहा था, फिर मैं निर्माणकर्ता से कहता हूं, लेकिन यह टुकड़े का सम्मान नहीं कर रहा था। ngOnInitहल चल रहा है :) धन्यवाद!
जोएल बाल्मर

क्या होगा यदि मेरा html एक घड़ीघर के रूप में "एचएच: एमएम" के माध्यम से क्लॉकवैल्यू () {रिटर्न डेटटाइम.टाइमएपीएमपीएम (नई तिथि ())} के माध्यम से रिटर्निंग टाइम के लिए बाध्य है, यह अंततः यात्रा के समय का पता लगाएगा जब पता चल रहा है, तो मैं कैसे कर सकता हूं इसे ठीक करो?
मेरियन

मुझे भी। यह भी पाया कि setInterval()कार्यों में लपेटना भी अगर यह अन्य जीवनकाल घटना कोड के बाद आग की जरूरत है।
रिक स्ट्राल

39

अपडेट करें

मैं बहुत पहले ओपी की स्वयं की प्रतिक्रिया के साथ शुरू करने की सलाह देता हूं : ठीक से इस बारे में सोचें कि constructorबनाम में क्या किया जा सकता है ngOnChanges()

मूल

यह एक उत्तर की तुलना में अधिक ध्यान देने योग्य है, लेकिन यह किसी की मदद कर सकता है। मैं इस समस्या पर अड़ गया जब एक बटन की उपस्थिति को फॉर्म की स्थिति पर निर्भर करने की कोशिश कर रहा है:

<button *ngIf="form.pristine">Yo</button>

जहाँ तक मुझे पता है, इस सिंटैक्स की स्थिति के आधार पर बटन को डोम से जोड़ा और हटाया जाता है। जो बदले में आगे बढ़ता है ExpressionChangedAfterItHasBeenCheckedError

मेरे मामले में सुधार (हालांकि मैं अंतर के पूर्ण निहितार्थों को समझने का दावा नहीं करता), display: noneइसके बजाय उपयोग करना था:

<button [style.display]="form.pristine ? 'inline' : 'none'">Yo</button>

6
NgIf बनाम शैली के बीच के अंतर के बारे में मेरी समझ यह है कि ngIf पृष्ठ में HTML को तब तक शामिल नहीं करता है जब तक कि स्थिति सही न हो, इस प्रकार "पृष्ठ भार" एक छोटे से कम हो जाता है, जबकि शैली तकनीक HTML को हमेशा के लिए कारण बनाती है पृष्ठ में और फॉर्म.प्रिस्टिन के मूल्य के आधार पर बस छिपाया या दिखाया गया है।
user3785010

4
आप [hidden]बहुत क्रिया [style.display]भाग के बजाय अच्छी तरह से उपयोग कर सकते हैं । :)
फिलिप मीस्नर

2
क्यों नहीं। हालांकि, के रूप में इस पृष्ठ पर एक और टिप्पणी में @Simon_Weaver से उल्लेख किया है, [hidden] हमेशा एक ही व्यवहार नहीं होगा के रूप मेंdisplay: none
अरनॉड पी

1
मैं प्रत्येक बटन में * ngIf के साथ दो अलग-अलग बटन (लॉगआउट / लॉगिन) दिखा रहा था और यह समस्या पैदा कर रहा था।
GoTo

कंस्ट्रक्टर मेरे लिए एक सही जगह थी, एक सामग्री स्नैक-बार का शुभारंभ
ऑस्टिन

31

दिलचस्प जवाब थे, लेकिन मुझे अपनी ज़रूरतों को पूरा करने के लिए कोई ऐसा नहीं मिला, जो @ चिट्रांग-मिश्रा से निकटतम हो जो केवल एक विशिष्ट फ़ंक्शन को संदर्भित करता है और मेरे ऐप में कई टॉगल नहीं है।

मैं DOM का हिस्सा नहीं होने [hidden]का फायदा उठाने के लिए उपयोग नहीं करना चाहता था *ngIfइसलिए मुझे निम्नलिखित समाधान मिला जो शायद सभी के लिए सबसे अच्छा नहीं हो सकता क्योंकि यह त्रुटि को ठीक करने के बजाय इसे दबा देता है, लेकिन मेरे मामले में जहां मुझे पता है अंतिम परिणाम सही है, यह मेरे ऐप के लिए ठीक लगता है।

मैंने जो किया वह लागू किया गया AfterViewChecked, constructor(private changeDetector : ChangeDetectorRef ) {}फिर जोड़ा गया

ngAfterViewChecked(){
  this.changeDetector.detectChanges();
}

मुझे उम्मीद है कि यह अन्य मदद करता है क्योंकि कई अन्य लोगों ने मेरी मदद की है।


3
क्या यह एक अनंत परिवर्तन का पता लगाने के लिए ट्रिगर नहीं होगा? मेरा मतलब है, आप जाँच के बाद परिवर्तनों के लिए पता लगा रहे हैं।
मैनुअल अजार

@ ManuelAzar जाहिरा तौर पर यह नहीं है। यह केवल समाधान है कि मेरे लिए काम किया है। मेरे सांत्वना में थोड़ा सा मौन। मैं इन सभी अप्रासंगिक परिवर्तन का पता लगाने में "त्रुटियों" से बहुत थक गया था।
जेरेमी थिल्ले

31

कोणीय परिवर्तन का पता लगाता है और जब इसका पता चलता है कि कुछ मान जो कि बच्चे के घटक को दिए गए हैं, बदल दिया गया है तो कोणीय त्रुटि को फेंकता है:

ExpressionChangedAfterItHasBeenCheckedError अधिक के लिए क्लिक करें

इसे ठीक करने के लिए हम AfterContentCheckedजीवन चक्र हुक और का उपयोग कर सकते हैं

import { ChangeDetectorRef, AfterContentChecked} from '@angular/core';

  constructor(
  private cdref: ChangeDetectorRef) { }

  ngAfterContentChecked() {

    this.cdref.detectChanges();

  }

हालाँकि यह समस्या को ठीक कर सकता है, लेकिन क्या यह बहुत विस्तारक और सीडी की ओवरकीलिंग नहीं है?
निकी

मुझे लगता है कि यह एकमात्र उत्तर है जो एक बच्चे को मूल्य (ओं) के कारण होने वाली इस त्रुटि को संबोधित करता है। धन्यवाद!
जावा-आदी ३०१

@ नमस्कार हाँ। हर बार जब भी आप स्क्रीन पर टच करते हैं, तो कहीं भी अनजाने में चेक किया जाता है () कहा जाता है
Mert Mertce

25

मेरे मामले में, मुझे अपने परीक्षण को चलाने के दौरान, मेरी कल्पना फ़ाइल में यह समस्या थी।

मैं परिवर्तन करना पड़ा ngIf करने के लिए [hidden]

<app-loading *ngIf="isLoading"></app-loading>

सेवा

<app-loading [hidden]="!isLoading"></app-loading>

1
के बारे में [hidden]: Talkdotnet.com/dont-use-hidden-attribute-angularjs-2
Simon_Weaver

2
यहाँ अंतर यह है कि *ngIfDOM से तत्व को जोड़ना, जोड़ना और पृष्ठ से हटाना, जबकि [hidden]DOM से इसे न हटाते हुए आइटम की दृश्यता में परिवर्तन होता है।
ग्रुंगोंडोला

5
लेकिन, यह वास्तव में असली समस्या को ठीक नहीं किया ...?
ravo10

23

नीचे दिए गए चरणों का पालन करें:

1. 'ChangeDetectorRef' का प्रयोग इस प्रकार करें:

import{ ChangeDetectorRef } from '@angular/core';

2. इसे कंस्ट्रक्टर () में लागू करें:

constructor(   private cdRef : ChangeDetectorRef  ) {}

3. अपने फ़ंक्शन के लिए निम्न विधि जोड़ें, जिसे आप बटन के क्लिक जैसी घटना पर बुला रहे हैं। तो यह इस तरह दिखता है:

functionName() {   
    yourCode;  
    //add this line to get rid of the error  
    this.cdRef.detectChanges();     
}

23

मैं ng2-carouselamos (कोणीय 8 और बूटस्ट्रैप 4) का उपयोग कर रहा था

मेरी समस्या के नीचे तय:

मैंने क्या किया:

1. implement AfterViewChecked,  
2. add constructor(private changeDetector : ChangeDetectorRef ) {} and then 
3. ngAfterViewChecked(){ this.changeDetector.detectChanges(); }

यह मदद करता है। गजब का!!
पथिक वेजानी

आपने मेरा दिन बचाया ... धन्यवाद!
ओमोस्टैन

19

मैं उसी समस्या का सामना कर रहा था क्योंकि मेरे घटक में सरणी में से एक में मूल्य बदल रहा था। लेकिन मूल्य परिवर्तन पर परिवर्तनों का पता लगाने के बजाय, मैंने घटक परिवर्तन का पता लगाने की रणनीति को बदल दिया onPush(जो वस्तु परिवर्तन पर परिवर्तनों का पता लगाएगा और परिवर्तन परिवर्तन पर नहीं)।

import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush
    selector: -
    ......
})

यह गतिशील रूप से नियंत्रणों को जोड़ने / हटाने के लिए काम करने लगता था .. क्या कोई कमियां हैं?
रिकार्डो सरैसिनो

मेरे हाथ में आई स्थिति में एक आकर्षण की तरह काम करता है, धन्यवाद! एक घटक एक "वैश्विक" वस्तु से जुड़ा हुआ था जो कहीं और बदल गया था और त्रुटि का कारण बना। इस घटक में पहले से ही अद्यतन हैंडलर था जब बाउंड ऑब्जेक्ट को अपडेट किया गया था, यह ईवेंट हैंडलर अब ChangeDetectionStrategy.OnPush के साथ संयोजन में changeDetectorRef.detectChanges () कॉल करता है। यह त्रुटि के बिना वांछित के रूप में काम करता है।
बर्नौली आईटी

@RicardoSaracino क्या आपको कोई कमियां मिली? मैं उसी चीज़ पर हैरान हो रहा था। मुझे पता है कि ओनपुश का पता लगाने का काम कैसे बदल जाता है, लेकिन सोच रहा था कि क्या कोई गोचरा है जो शायद मुझे याद आ रहा है। मैं वापस सर्कल नहीं करना चाहता।
mtpultz

@RicardoSaracino, हाँ, यह कुछ कमियां भी हैं, तो आप इस विस्तृत लिंक का उल्लेख कर सकते blog.angular-university.io/onpush-change-detection-how-it-works
धीरज

@BernoulliIT धन्यवाद, मुझे खुशी है कि इसने आपके लिए काम किया।
धीरज

17

इस लेख का जिक्र https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchanchanaaititbebeencheckederror-error-e3fn9ce7db4

तो परिवर्तन का पता लगाने के पीछे यांत्रिकी वास्तव में एक तरह से काम करता है कि परिवर्तन का पता लगाने और सत्यापन पचाने दोनों को सिंक्रोनाइज़ किया जाता है। इसका मतलब है, अगर हम संपत्तियों को अतुल्यकालिक रूप से अपडेट करते हैं, तो सत्यापन लूप के चलने पर मानों को अपडेट नहीं किया जाएगा और हमें ExpressionChanged...त्रुटि नहीं मिलेगी । इस त्रुटि के कारण के सत्यापन की प्रक्रिया के दौरान, कोणीय विभिन्न मानों को देखता है और फिर परिवर्तन का पता लगाने के चरण के दौरान इसे दर्ज करता है। जिससे बचने के लिए…।

1) ChangeDetectorRef का उपयोग करें

2) setTimeOut का उपयोग करें। यह आपके कोड को दूसरे वीएम में मैक्रो-टास्क के रूप में निष्पादित करेगा। सत्यापन प्रक्रिया के दौरान कोणीय इन परिवर्तनों को नहीं देखेंगे और आपको वह त्रुटि नहीं मिलेगी।

 setTimeout(() => {
        this.isLoading = true;
    });

3) यदि आप वास्तव में उसी वीएम उपयोग पर अपने कोड को निष्पादित करना चाहते हैं जैसे

Promise.resolve(null).then(() => this.isLoading = true);

यह एक माइक्रो-टास्क बनाएगा। वर्तमान समकालिक कोड को निष्पादित करने के बाद माइक्रो-कार्य कतार संसाधित होती है इसलिए संपत्ति का अद्यतन सत्यापन चरण के बाद होगा।


क्या आप शैली अभिव्यक्ति के साथ विकल्प # 3 का उपयोग कर सकते हैं? मेरे पास ऊंचाई के लिए एक शैली अभिव्यक्ति है जिसे अंतिम रूप से मूल्यांकन किया जाना चाहिए, क्योंकि यह इंजेक्शन की सामग्री पर आधारित है।
N-

1
क्षमा करें, अभी आपकी टिप्पणी देखी गई, हाँ मुझे कोई कारण नहीं दिखाई देता है कि क्यों नहीं। ताकि स्टाइल में बदलाव के साथ-साथ काम भी हो।
ATHER

4

@HostBinding इस त्रुटि का एक भ्रामक स्रोत हो सकता है।

उदाहरण के लिए, हम कहते हैं कि आपके पास घटक में निम्नलिखित होस्ट बाइंडिंग है

// image-carousel.component.ts
@HostBinding('style.background') 
style_groupBG: string;

सादगी के लिए, इस संपत्ति को निम्नलिखित इनपुट संपत्ति के माध्यम से अद्यतन किया गया है:

@Input('carouselConfig')
public set carouselConfig(carouselConfig: string) 
{
    this.style_groupBG = carouselConfig.bgColor;   
}

मूल घटक में आप इसे प्रोग्रामेटिक रूप से सेट कर रहे हैं ngAfterViewInit

@ViewChild(ImageCarousel) carousel: ImageCarousel;

ngAfterViewInit()
{
    this.carousel.carouselConfig = { bgColor: 'red' };
}

यहाँ क्या होता है:

  • आपका मूल घटक बनाया गया है
  • ImageCarousel घटक बनाया गया है, और carouselViewChild के माध्यम से सौंपा गया है
  • हम carouselतब तक पहुँच नहीं सकते हैं ngAfterViewInit()(यह शून्य होगा)
  • हम कॉन्फ़िगरेशन असाइन करते हैं, जो सेट करता है style_groupBG = 'red'
  • यह background: redमेजबान ImageCarousel घटक पर बदले में सेट होता है
  • यह घटक आपके मूल घटक का 'स्वामित्व' है, इसलिए जब यह परिवर्तनों की जाँच करता है तो इसे एक परिवर्तन मिलता है carousel.style.backgroundऔर यह जानने के लिए पर्याप्त चतुर नहीं है कि यह कोई समस्या नहीं है इसलिए यह अपवाद फेंकता है।

एक समाधान के लिए एक और रैपर div अंदरूनी सूत्र ImageCarousel शुरू करने और उस पर पृष्ठभूमि का रंग सेट करने के लिए है, लेकिन तब आपको उपयोग करने के कुछ लाभ नहीं मिलते हैं HostBinding(जैसे कि माता-पिता को ऑब्जेक्ट के पूर्ण सीमा को नियंत्रित करने की अनुमति देना)।

पैरेंट घटक में बेहतर समाधान, विन्यास सेट करने के बाद डिटेचेंजेज () जोड़ना है।

ngAfterViewInit()
{
    this.carousel.carouselConfig = { ... };
    this.cdr.detectChanges();
}

यह इस तरह से स्पष्ट रूप से सेट किया हुआ लग सकता है, और अन्य उत्तरों के समान है लेकिन सूक्ष्म अंतर है।

उस मामले पर विचार करें जहां आप @HostBindingविकास के दौरान बाद में नहीं जोड़ते हैं । अचानक आपको यह त्रुटि मिलती है और इसका कोई मतलब नहीं है।


2

यहाँ क्या हो रहा है पर मेरे विचार हैं। मैंने दस्तावेज़ीकरण नहीं पढ़ा है लेकिन मुझे यकीन है कि यह त्रुटि क्यों दिखाई गई इसका एक हिस्सा है।

*ngIf="isProcessing()" 

* NgIf का उपयोग करते समय, यह हर बार स्थिति बदलने पर तत्व को जोड़कर या हटाकर डोम को बदल देता है। इसलिए यदि स्थिति को दृश्य में प्रस्तुत करने से पहले बदल जाता है (जो कि कोणीय की दुनिया में अत्यधिक संभव है), तो त्रुटि को फेंक दिया जाता है। विकास और उत्पादन मोड के बीच यहाँ स्पष्टीकरण देखें ।

[hidden]="isProcessing()"

[hidden]इसका उपयोग करते समय यह शारीरिक रूप से नहीं बदलता है, DOMलेकिन केवल elementदृश्य से छिपा होता है , सबसे अधिक संभावना CSSहै पीठ में उपयोग करना । तत्व अभी भी DOM में है लेकिन स्थिति के मूल्य के आधार पर दिखाई नहीं देता है। इसीलिए उपयोग करते समय त्रुटि नहीं होगी [hidden]


यदि isProcessing()एएमई बात कर रहा है, आप का उपयोग करना चाहिए !isProcessing()के लिए[hidden]
माथीउ चार्बोनियर

hidden"पीठ में सीएसएस का उपयोग नहीं करता है", यह एक नियमित HTML संपत्ति है। developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/…
Lazar Ljubenović

1

मेरे मुद्दे के लिए, मैं github पढ़ रहा था - "ExpressionChangedAfterItHasBeenCheckedError जब एक घटक 'नॉन मॉडल' का मूल्य afterViewInit में बदल रहा है" और ngModel को जोड़ने का फैसला किया

<input type="hidden" ngModel #clientName />

इसने मेरा मुद्दा ठीक कर दिया, मुझे उम्मीद है कि यह किसी की मदद करेगा।


1
उस साइट पर इसे जोड़ने के लिए कहां कहा जाता है ngModel। और क्या आप कृपया विस्तृत रूप से बता सकते हैं कि यह क्यों सहायक होना चाहिए?
पीटर विप्परमन

जब मैं इस मुद्दे को ट्रैक कर रहा था, तो इसने मुझे लिंक की जांच करने के लिए प्रेरित किया। लेख पढ़ने के बाद मैंने विशेषता को जोड़ा और इसने मेरा मुद्दा तय किया। अगर कोई इसी मुद्दे पर चलता है तो यह मददगार होता है।
डेमोड्वे जुले

1

डिबगिंग टिप्स

यह त्रुटि काफी भ्रामक हो सकती है, और यह गलत होने के बारे में गलत धारणा बनाना आसान है। मुझे उपयुक्त स्थानों में प्रभावित घटकों में इस तरह के बहुत सारे डिबगिंग स्टेटमेंट जोड़ना मददगार लगता है। इससे प्रवाह को समझने में मदद मिलती है।

माता-पिता में इस तरह के बयान (सटीक स्ट्रिंग 'महत्वपूर्ण है' महत्वपूर्ण है), लेकिन इसके अलावा ये सिर्फ इस तरह हैं:

    console.log('EXPRESSIONCHANGED - HomePageComponent: constructor');
    console.log('EXPRESSIONCHANGED - HomePageComponent: setting config', newConfig);
    console.log('EXPRESSIONCHANGED - HomePageComponent: setting config ok');
    console.log('EXPRESSIONCHANGED - HomePageComponent: running detectchanges');

बच्चे / सेवाओं / टाइमर कॉलबैक में:

    console.log('EXPRESSIONCHANGED - ChildComponent: setting config');
    console.log('EXPRESSIONCHANGED - ChildComponent: setting config ok');

यदि आप detectChangesमैन्युअल रूप से चलाते हैं तो उसके लिए लॉगिंग भी जोड़ें:

    console.log('EXPRESSIONCHANGED - ChildComponent: running detectchanges');
    this.cdr.detectChanges();

फिर क्रोम डीबगर में 'EXPRESSIONCHANGES' द्वारा फ़िल्टर करें। यह आपको हर चीज के प्रवाह और क्रम को दिखाएगा, जो सेट हो जाता है, और यह भी कि कोणीय किस बिंदु पर त्रुटि फेंकता है।

यहां छवि विवरण दर्ज करें

आप विराम बिंदुओं को डालने के लिए ग्रे लिंक पर भी क्लिक कर सकते हैं।

यह देखने के लिए एक और बात कि क्या आपके आवेदन में समान नाम वाले गुण हैं (जैसे कि style.background) सुनिश्चित करें कि आप अपने विचार वाले व्यक्ति को डीबग कर रहे हैं - इसे अस्पष्ट रंग मान पर सेट करके।


1

मेरे मामले में, मेरे पास LoadingServiceBehavioralSubject के साथ एक async संपत्ति थीisLoading

[छिपे हुए] मॉडल का उपयोग करना काम करता है, लेकिन * ngIf विफल रहता है

    <h1 [hidden]="!(loaderService.isLoading | async)">
        THIS WORKS FINE
        (Loading Data)
    </h1>

    <h1 *ngIf="!(loaderService.isLoading | async)">
        THIS THROWS ERROR
        (Loading Data)
    </h1>

1

एक समाधान जो rxjs का उपयोग करके मेरे लिए काम करता है

import { startWith, tap, delay } from 'rxjs/operators';

// Data field used to populate on the html
dataSource: any;

....

ngAfterViewInit() {
  this.yourAsyncData.
      .pipe(
          startWith(null),
          delay(0),
          tap((res) => this.dataSource = res)
      ).subscribe();
}

समस्यात्मक कोड क्या था? यहाँ क्या उपाय है?
mkb

हाय @ mkb मुद्दा ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.तब था जब मूल्य में परिवर्तन होता है जब DOM बदल जाता है
संदीप के नायर

नमस्ते, मेरा मतलब है कि समस्या को दूर करने के लिए आपने यहां क्या किया। आपने विलंबित () या जोड़े गए प्रारंभ () को जोड़ने से पहले rxjs का उपयोग नहीं किया? मैं पहले से ही विभिन्न rxjs विधियों के साथ rxjs का उपयोग करता हूं, लेकिन फिर भी त्रुटि मिलती है, मुझे
मिस्टी

जोड़ा delayत्रुटि को दूर कर देता है। यह इसी तरह काम करता है setTimeout
लजार लुजुबेनोविक

1

Ionic3 में मुझे इस तरह की त्रुटि हुई (जो प्रौद्योगिकी स्टैक के भाग के रूप में कोणीय 4 का उपयोग करता है)।

मेरे लिए यह कर रहा था:

<ion-icon [name]="getFavIconName()"></ion-icon>

इसलिए मैं सशर्त एक के प्रकार बदलने के लिए कोशिश कर रहा था आयन आइकन एक से pinएक करने के लिए remove-circle, एक विधा प्रति एक स्क्रीन पर काम कर रहा था।

मैं अनुमान लगा रहा हूं कि मुझे *ngIfइसके बजाय जोड़ना होगा।


1

मेरा मुद्दा तब सामने आया जब मैंने जोड़ा *ngIfलेकिन वह कारण नहीं था। {{}}टैग में मॉडल को बदलने के बाद त्रुटि हुई थी, फिर *ngIfबाद में बयान में बदले हुए मॉडल को प्रदर्शित करने की कोशिश की गई। यहाँ एक उदाहरण है:

<div>{{changeMyModelValue()}}</div> <!--don't do this!  or you could get error: ExpressionChangedAfterItHasBeenCheckedError-->
....
<div *ngIf="true">{{myModel.value}}</div>

समस्या को ठीक करने के लिए, मैं बदल गया, जहां मैंने changeMyModelValue()उस स्थान पर कॉल किया, जिसने अधिक समझ बनाई।

अपनी स्थिति में मैं चाहता था changeMyModelValue()कि जब भी कोई बच्चा घटक डेटा बदले। इसके लिए मुझे चाइल्ड कंपोनेंट में एक ईवेंट बनाना और फेंकना पड़ता है ताकि अभिभावक इसे संभाल कर (कॉल करके changeMyModelValue()देख सकें) https://angular.io/guide/component-interaction#parent-listens-for-child-event


0

मुझे आशा है कि यह किसी को यहां आने में मदद करता है: हम ngOnInitनिम्नलिखित तरीके से सेवा कॉल करते हैं और displayMainतत्वों के बढ़ते हुए डोम को नियंत्रित करने के लिए एक चर का उपयोग करते हैं।

component.ts

  displayMain: boolean;
  ngOnInit() {
    this.displayMain = false;
    // Service Calls go here
    // Service Call 1
    // Service Call 2
    // ...
    this.displayMain = true;
  }

और घटक। html

<div *ngIf="displayMain"> <!-- This is the Root Element -->
 <!-- All the HTML Goes here -->
</div>

0

मुझे यह त्रुटि मिली क्योंकि मैं घटक में एक चर का उपयोग कर रहा था। एक बार जब मैंने HTML में भाग हटा दिया, तो यह त्रुटि हो गई थी।


0

मुझे यह त्रुटि मिली क्योंकि मैं मोडल में रिड्यूक्स कार्यों को भेज रहा था और उस समय मोडल नहीं खोला गया था। मैं क्षणों मोडल घटक को पुनः प्राप्त करने के इनपुट भेज रहा था। इसलिए मैंने यह सुनिश्चित करने के लिए कि वहां मोडल खोला है और फिर कार्रवाई को रोक दिया जाता है, वहां सेटटाइमआउट किया।


0

इससे जूझ रहे किसी को भी। यहाँ इस त्रुटि को ठीक से डीबग करने का एक तरीका है: https://blog.angular-university.io/angular-debugging/

मेरे मामले में, वास्तव में मुझे इस त्रुटि का उपयोग करके छुटकारा मिला [*] बजाय छिपा हुआ हैक * ngIf ...

लेकिन लिंक मैं प्रदान की खोजने के लिए मुझे सक्षम दोषी * ngIf :)

का आनंद लें।


के hiddenबजाय का उपयोग कर ngIfएक हैक नहीं है, और न ही यह मुद्दे के मूल को संबोधित करता है। आप समस्या को दूर कर रहे हैं।
लजार लुजुबेनोविक

-2

समाधान ... सेवाओं और rxjs ... ईवेंट एमिटर और प्रॉपर्टी बाइंडिंग दोनों ही rxjs का उपयोग करते हैं..आप इसे अपने स्वयं को लागू करने के लिए बेहतर हैं, अधिक नियंत्रण, डीबग करना आसान। याद रखें कि ईवेंट एमिटर rxjs का उपयोग कर रहे हैं। बस, एक सेवा बनाएं और एक अवलोकन के भीतर, प्रत्येक घटक को थान पर्यवेक्षक की सदस्यता लें और जरूरत के अनुसार नए मूल्य या कॉशन मूल्य को पास करें


1
इतना ही नहीं इस सवाल का जवाब नहीं है, यह भी भयानक सलाह है। दोस्तों, कृपया अपने आप को rxjs को फिर से लागू न करें क्योंकि आप कोणीय की सीडी त्रुटियां हो रही हैं। :)
लज़ार लुजुबेनोविक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.