ExpressionChangedAfterItHasBeenCheckedError Açıklaması


308

Lütfen bana neden bu hatayı almaya devam ettiğimi açıklayın: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.

Açıkçası, sadece dev modunda alıyorum, üretim yapımımda gerçekleşmiyor, ama çok sinir bozucu ve sadece geliştirme ortamımda eşyada görünmeyecek bir hataya sahip olmanın faydalarını anlamıyorum - - Muhtemelen anlayış eksikliğim yüzünden.

Genellikle, düzeltme yeterince kolaydır, sadece böyle bir setTimeout kod neden hata sarın:

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

Veya aşağıdaki gibi bir kurucu ile değişiklikleri algılamaya zorlayın constructor(private cd: ChangeDetectorRef) {}:

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

Ama neden sürekli olarak bu hatayla karşılaşıyorum? Bunu anlamak istiyorum, böylece gelecekte bu hileli düzeltmelerden kaçınabiliyorum.


Yanıtlar:


121

Benzer bir sorunum vardı. Baktığımızda yaşam döngüsü kanca dokümantasyon , ben değiştim ngAfterViewInitiçin ngAfterContentInitve işe yaradı.


@PhilipEnc sorunum DOM değişikliğinin tetiklediği bir değişiklikle ilgiliydi. DOM değiştiğinde, QueryList nesnesi (bir @ContentChildren özelliğinden gelir) güncellenir ve güncelleştirmenin çağırdığı yöntemin içinde iki yönlü bağlı özelliği değiştirir. Bu benim yaşadığım problemi yarattı. İki mülkte yapılan değişikliği setTimeoutyukarıda gösterdiğiniz gibi sarmak hile yaptı. Teşekkürler!
kbpontius

1
Benim durumumda ngAfterContentInit primeng ızgara dizi değerini değiştiren bazı kod yerleştirmişti, ben ngOnInit kod yerleştirdi ve çalıştı.
Vibhu

ngAfterContentCheckedngAfterContentInithala hata atarken burada çalışıyor .
ashubuntu

Kontrol edilen kullanım ancak proje çok yavaş yüklendi
Ghotekar Rahul

101

Bu hata, uygulamanızdaki gerçek bir sorunu gösterir, bu nedenle bir istisna atmak mantıklıdır.

Gelen devModedeğişim algılama modeli değişip değişmediğini kontrol etmek için her düzenli değişim algılama yayınlandıktan sonra ek bir oynama ekler.

Model, normal ve ek değişiklik algılama dönüşü arasında değiştiyse,

  • değişiklik algılamanın kendisi bir değişikliğe neden oldu
  • bir yöntem veya alıcı her çağrıldığında farklı bir değer döndürür

ikisi de kötü, çünkü nasıl ilerleyeceği belli değil çünkü model asla stabilize olmayabilir.

Açısal çalışma, model kararlı hale gelene kadar değişiklik algılamayı değiştirirse, sonsuza kadar çalışabilir. Açısal değişiklik algılama yapmazsa, görünüm modelin geçerli durumunu yansıtmayabilir.

Ayrıca bkz . Angular2'de üretim ve geliştirme modu arasındaki fark nedir?


4
Gelecekte bu hatayı görmekten nasıl kaçınabilirim? Aynı hataları yapmamak için kodumu düşünmem gereken farklı bir yol var mı?
Kevin LeStarge

25
Genellikle bu gibi bazı yaşam döngüsü geri aramaları neden olur ngOnInitya da ngOnChangesmodeli (bazı yaşam döngüsü geri aramalar, bir tane yapmak ya da yapma tam olarak hangi kendimi hatırlamıyorum yok modeli başkalarını değiştirmek izin) değiştirme. Görünümdeki yöntemlere veya işlevlere bağlanmayın, bunun yerine alanlara bağlanın ve olay işleyicilerindeki alanları güncelleyin. Yöntemlere bağlanmanız gerekiyorsa, gerçekte bir değişiklik olmadığı sürece aynı değer örneğini döndürdüğünden emin olun. Değişiklik tespiti bu yöntemleri çok çağıracaktır.
Günter Zöchbauer

Buraya gelen, ngx-tost makinesi kütüphanesini kullanarak bu hatayı alan herkes için hata raporu şöyledir
rmcsharry

2
Uygulama ile ilgili bir sorun olması gerekmez. Çağrının changeRef.detectChanges()bir çözüm olması / hatayı bastırması, bunun kanıtıdır. $scope.$watch()Angular 1'deki durumu değiştirmek gibi .
Kevin Beal

1
Açısal 1'i çok iyi bilmiyorum ama Açısal 2'deki değişiklik algılama oldukça farklı çalışıyor. Bunun mutlaka bir sorun olmadığı konusunda haklısınız, ancak genellikle cdRef.detectChanges()sadece bazı garip kenar durumlarda gereklidir ve ihtiyaç duyduğunuzda nedenini anladığınızı dikkatlice görmelisiniz.
Günter Zöchbauer

83

Açısal Yaşam Döngüsü Kancalarını ve bunların değişim algılama ile ilişkilerini anladığımda çok fazla anlayış geldi .

Angular'ı *ngIfbir öğeye bağlı global bir bayrağı güncellemeye çalışıyordum ngOnInit()ve başka bir bileşenin yaşam döngüsü kancasındaki bayrağı değiştirmeye çalışıyordum .

Belgelere göre, bu yöntem Angular zaten değişiklikler tespit ettikten sonra çağrılır:

İlk ngOnChanges () 'den sonra bir kez çağrılır.

Dolayısıyla, içindeki bayrağın güncellenmesi ngOnChanges()değişiklik algılamayı başlatmaz. Ardından, değişiklik algılaması yeniden doğal olarak tetiklendikten sonra, bayrağın değeri değişti ve hata atıldı.

Benim durumumda bunu değiştirdim:

constructor(private globalEventsService: GlobalEventsService) {

}

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

Buna:

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

ngOnInit() {

}

ve sorunu düzeltti :)


3
Benim sorunum da benzerdi. Uzun saatler sonra bir hata yaptım ve ngOnInit işlevi ve yapıcı dışında bir değişken tanımladı. Bu, initalizasyon fonksiyonuna yerleştirilen bir gözlemlenebilir cihazdan veri değişiklikleri alır. Hatayı düzeltmek için sizinle aynı şeyi yaptım.
ravo10

1
Her yerde çok benzer, ancak router.navigateURL'de mevcutsa bir parçaya yüklendiğinde ( ) ilerlemeye çalışıyordum . Bu kod başlangıçta AfterViewInithatayı aldığım yere yerleştirildi , sonra yapıcıya söylediğin gibi taşındım ama parçaya saygı duymuyordu. Çözüldü taşındı ngOnInit:) teşekkürler!
Joel Balmer

Benim html, getVerue () {return DateTime.TimeAMPM (new Date ())} aracılığıyla "HH: MM" olarak bir alıcıya dönüş zamanına bağlıysa, algılama çalışırken dakikalar değiştiğinde sonunda açılacaktır, nasıl yapabilirim bunu tamir et?
Meryan

Burada aynı. Ayrıca, setInterval()diğer ömür boyu olay kodundan sonra ateşlenmesi gerekiyorsa da sarmanın işe yaradığını buldu .
Rick Strahl

39

Güncelleme

İlk önce OP'nin kendi tepkisi ile başlamayı şiddetle tavsiye ederim : constructorvs'de ne yapılması gerektiğini doğru bir şekilde düşünün ngOnChanges().

orijinal

Bu bir cevaptan çok bir yan nottur, ancak birisine yardımcı olabilir. Bir düğme varlığını formun durumuna bağlı yapmaya çalışırken bu sorun üzerinde tökezledi:

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

Bildiğim kadarıyla, bu sözdizimi, düğmeye bağlı olarak DOM'a eklenen ve kaldırılan düğmeye yol açar. Hangi sırayla yol açar ExpressionChangedAfterItHasBeenCheckedError.

Benim durumumdaki düzeltme (farkın tüm etkilerini kavradığını iddia etmeme rağmen), display: nonebunun yerine kullanmaktı :

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

6
NgIf ve stil arasındaki farkı anlamak, ngIf'in koşul doğru olana kadar HTML'yi sayfaya dahil etmemesi, böylece stil tekniği HTML'nin her zaman şeklinde saklanır ve form.pristine değerine göre gizlenir veya gösterilir.
user3785010

4
[hidden]Çok ayrıntılı [style.display]kısım yerine de kullanabilirsiniz . :)
Philipp Meissner

2
Neden olmasın. Bu sayfadaki başka bir yorumda @Simon_Weaver tarafından belirtildiği gibi, [hidden] her zaman aynı davranışa sahip olmayacak olsa dadisplay: none
Arnaud P

1
Her düğmede * ngIf ile iki farklı düğme (oturum kapatma / oturum açma) gösteriyordum ve bu soruna neden oluyordu.
GoTo

Yapıcı benim için doğru yerdi, malzeme atıştırmalık bir bar başlattı
austin

31

İlginç cevaplar vardı ama benim ihtiyaçlarına uygun bir tane bulamadım, en yakın olan @ chittrang-mishra sadece belirli bir işleve atıfta bulunur ve benim uygulamada olduğu gibi birkaç geçiş yapar.

DOM'un bir parçası olmamaktan [hidden]faydalanmak istemedim, *ngIfbu yüzden hatayı düzeltmek yerine hatayı bastırdığı için herkes için en iyi olmayabilir aşağıdaki çözümü buldum, ancak benim durumumda nihai sonuç doğru, benim app için tamam görünüyor.

Yaptığım, uygulamak AfterViewChecked, eklemek constructor(private changeDetector : ChangeDetectorRef ) {}ve sonra

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

Umarım diğerleri bana yardımcı olduğu için bu başkalarına yardımcı olur.


3
Bu sonsuz bir değişiklik algılama döngüsünü tetiklemez mi? yani kontrol ettikten sonra değişiklikleri tespit ediyorsunuz.
Manuel Azar

@ManuelAzar Görünüşe göre öyle değil. Bu benim için çalışan SADECE çözüm. Son konsolumda biraz sessizlik. Tüm bu alakasız değişiklik tespiti "hatalarından" çok yoruldum.
Jeremy Thille

31

Açısal çalıştırma değişiklik algılaması ve alt bileşene iletilen bazı değerlerin değiştiğini tespit ettiğinde, Açısal hatayı atar:

ExpressionChangedAfterItHasBeenCheckedError devamı için tıklayın

Bunu düzeltmek için AfterContentCheckedyaşam döngüsü kancasını kullanabilir ve

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

  constructor(
  private cdref: ChangeDetectorRef) { }

  ngAfterContentChecked() {

    this.cdref.detectChanges();

  }

Bu sorunu çözse de, bu çok geniş ve CD'yi aşırı dolduruyor mu?
Nicky

Bence bu hata bir çocuğa değer (ler) geçirerek kaynaklanan bu hata giderir tek cevap bu. Teşekkürler!
java-addict301

@Nicky Evet. Ekrana her dokunduğunuzda, istediğiniz yerde ngAfterContentChecked () denir
Mert Mertce

25

Benim durumumda, testlerimi çalıştırırken spec dosyamda bu sorunu yaşadım.

Ben değişikliğine vardı ngIf için [hidden]

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

için

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


2
Buradaki fark *ngIf, öğeyi sayfadan ekleyip kaldırarak DOM'yi [hidden]değiştirirken, öğenin DOM'dan kaldırılmadan görünürlüğünü değiştirmesidir.
Grungondola

5
Ama bu gerçek problemi gerçekten çözmedi ...?
ravo10

23

Aşağıdaki adımları izleyin:

1. @ açısal / çekirdekten aşağıdaki şekilde aktararak 'ChangeDetectorRef' kullanın:

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

2. Yapıcı () içine aşağıdaki gibi uygulayın:

constructor(   private cdRef : ChangeDetectorRef  ) {}

3. Aşağıdaki yöntemi, düğmeyi tıklatma gibi bir olayda çağırdığınız işlevlere ekleyin. Yani şuna benziyor:

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

23

I edildi NG2-carouselamos (Açısal 8 ve özyükleme 4) kullanılarak

Aşağıda sorunumu çözdüm:

Ben ne yaptım:

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

Yardımcı oldu. İnanılmaz!!
Pathik Vejani

Günümü kurtardın ... Teşekkürler!
omostan

19

Bileşenimdeki diziden birinde değer değişiyordu aynı sorunla karşı karşıyaydım. Ancak değer değişimindeki değişiklikleri saptamak yerine, bileşen değişikliği algılama stratejisini onPush(değer değişiminde değil, nesne değişimindeki değişiklikleri algılayacak) olarak değiştirdim.

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

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

Bu, kontrolleri dinamik olarak eklemek / kaldırmak için çalışıyor gibi görünüyordu .. Herhangi bir dezavantajı var mı?
Ricardo Saracino

Elimdeki durumda bir cazibe gibi çalışıyor, teşekkürler! Bir bileşen, başka bir yerde değiştirilen ve Hatanın oluşmasına neden olan "genel" bir nesneye bağlandı. Bu bileşen, bağlı nesnenin güncelleştirildiği zaman için zaten bir güncelleştirme işleyicisine sahipti, bu olay işleyicisi artık ChangeDetectionStrategy.OnPush ile birlikte changeDetectorRef.detectChanges () yöntemini çağırıyor.
Bernoulli IT

@RicardoSaracino herhangi bir dezavantaj buldunuz mu? Ben de aynı şeyi merak ediyordum. Değişiklik tespiti OnPush'ın nasıl çalıştığını biliyorum, ama belki de eksik olduğum bir gotcha olup olmadığını merak ediyorum. Geri dönmek zorunda kalmak istemiyorum.
mtpultz

@RicardoSaracino, Evet bazı dezavantajları var, bu ayrıntılı bağlantıya başvurabilirsiniz blog.angular-university.io/onpush-change-detection-how-it-works
Dheeraj

@BernoulliIT Teşekkürler, sizin için çalıştığı için memnunum.
Dheeraj

17

Https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4 makalesine atıfta bulunarak

Dolayısıyla, değişiklik algılamanın arkasındaki mekanik aslında değişiklik algılama ve doğrulama özetlerinin eşzamanlı olarak gerçekleştirileceği şekilde çalışır. Bu, özellikleri eşzamansız olarak güncellersek, doğrulama döngüsü çalışırken değerler güncellenmeyecek ve ExpressionChanged...hata almayacağız . Bu hatayı almamızın nedeni, doğrulama işlemi sırasında Angular, değişiklik algılama aşamasında kaydettiklerinden farklı değerler görmesidir. Bundan kaçınmak için ....

1) changeDetectorRef kullanın

2) setTimeOut'u kullanın. Bu, kodunuzu başka bir sanal makinede makro görevi olarak yürütür. Açısal, doğrulama işlemi sırasında bu değişiklikleri görmez ve bu hatayı alamazsınız.

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

3) Kodunuzu gerçekten aynı VM kullanımında yürütmek istiyorsanız,

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

Bu bir mikro görev yaratacaktır. Mikro görev kuyruğu, geçerli eşzamanlı kod yürütme işlemi bittikten sonra işlenir, bu nedenle özelliğe yönelik güncelleme doğrulama adımından sonra gerçekleşir.


3 numaralı seçeneği bir stil ifadesiyle kullanabilir misiniz? En son enjekte edilen içeriğe dayandığı için en son değerlendirilmesi gereken bir stil ifadesine sahibim.
N-ate

1
Üzgünüm sadece yorumunu gördüm, evet neden olmasın herhangi bir neden görmüyorum. Bu da stil değişiklikleriyle çalışmalı.
18

4

@HostBinding bu hatanın kafa karıştırıcı bir kaynağı olabilir.

Örneğin, bir bileşende aşağıdaki ana bilgisayar bağına sahip olduğunuzu varsayalım

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

Kolaylık olması açısından, bu özelliğin aşağıdaki input özelliği üzerinden güncellendiğini varsayalım:

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

Üst bileşende, programlı olarak ngAfterViewInit

@ViewChild(ImageCarousel) carousel: ImageCarousel;

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

İşte olanlar:

  • Ana bileşeniniz oluşturuldu
  • ImageCarousel bileşeni oluşturulur ve carousel(ViewChild aracılığıyla)
  • Biz erişemez carouselkadar ngAfterViewInit()(o boş olacaktır)
  • Ayarlanan yapılandırmayı atarız style_groupBG = 'red'
  • Bu background: redda ana ImageCarousel bileşeninde ayarlanır
  • Bu bileşenin üst bileşeniniz tarafından `` sahip olduğu '', bu nedenle değişiklikleri kontrol ettiğinde bir değişiklik bulur carousel.style.backgroundve bunun bir sorun olmadığını bilecek kadar zeki değildir, bu nedenle istisnayı atar.

Bir çözüm, başka bir sarmalayıcı div içeriden ImageCarousel'i tanıtmak ve bunun üzerinde arka plan rengini ayarlamaktır, ancak daha sonra kullanmanın bazı avantajlarından yararlanamazsınız HostBinding(örneğin, ebeveynin nesnenin tüm sınırlarını kontrol etmesine izin vermek gibi).

Ana bileşendeki daha iyi çözüm, config ayarlandıktan sonra detChanges () eklenmesidir.

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

Bu, bu şekilde ortaya çıkmış gibi görünebilir ve diğer cevaplara çok benzeyebilir, ancak ince bir fark vardır.

@HostBindingGeliştirme sırasında daha sonraya kadar eklemediğiniz durumu düşünün . Aniden bu hatayı alıyorsunuz ve herhangi bir anlam ifade etmiyor gibi görünüyor.


2

İşte neler olduğuna dair düşüncelerim. Belgeleri okumadım, ancak hatanın neden gösterildiğinin bir parçası olduğundan eminim.

*ngIf="isProcessing()" 

* NgIf kullanırken, koşul her değiştiğinde öğeyi ekleyerek veya kaldırarak DOM'yi fiziksel olarak değiştirir. Dolayısıyla koşul görünüme dönüştürülmeden önce değişirse (Angular'ın dünyasında oldukça olasıdır), hata atılır. Açıklamaya bakın burada geliştirme ve üretim modları arasında.

[hidden]="isProcessing()"

Kullanırken [hidden]fiziksel olarak değişmez, DOMsadece arkadan elementgörünümden gizlenir CSS. Öğe DOM'da hala var, ancak koşulun değerine bağlı olarak görünmüyor. Bu yüzden kullanırken hata oluşmaz [hidden].


Eğer isProcessing()ame şeyi yapıyor, kullanmak gerekir !isProcessing()için[hidden]
Matthieu Charbonnier

hidden"arkada CSS kullanmaz", normal bir HTML özelliğidir. developer.mozilla.org/tr-TR/docs/Web/HTML/Global_attributes/…
Lazar Ljubenović

1

Benim sorunum için github okuyordum - "ExpressionChangedAfterItHasBeenCheckedError afterViewInit bileşen 'model olmayan' değeri değiştirirken" ve ngModel eklemeye karar verdi

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

Sorunumu düzeltti, umarım birine yardımcı olur.


1
Bu siteye nerelere ekleneceğini söylüyor ngModel. Ve lütfen bunun neden faydalı olması gerektiğini açıklayabilir misiniz?
Peter Wippermann

Bu sorunu takip ederken bağlantıyı araştırmamı sağladı. Makaleyi okuduktan sonra özelliği ekledim ve sorunumu düzeltti. Birisi aynı sorunla karşılaşırsa yardımcı olur.
Demodave

1

Hata ayıklama ipuçları

Bu hata oldukça kafa karıştırıcı olabilir ve tam olarak ne zaman oluştuğu hakkında yanlış bir varsayım yapmak kolaydır. Etkilenen bileşenler boyunca uygun yerlerde çok sayıda hata ayıklama ifadesi eklemeyi yararlı buluyorum. Bu akışı anlamaya yardımcı olur.

Ebeveynte böyle ifadeler koydu ('EXPRESSIONCHANGED' tam dizesi önemlidir), ancak bunun dışında sadece örnekler:

    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');

Alt / hizmetler / zamanlayıcı geri aramalarında:

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

Bunun detectChangesiçin manuel olarak günlük kaydı eklerseniz:

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

Ardından Chrome hata ayıklayıcısında sadece 'EXPRESSIONCHANGES' ile filtreleyin. Bu, tam olarak ayarlanan her şeyin akışını ve sırasını ve aynı zamanda Angular'ın hatayı hangi noktada attığını gösterir.

resim açıklamasını buraya girin

Kesme noktalarını koymak için gri bağlantıları da tıklayabilirsiniz.

Uygulamanız boyunca benzer şekilde adlandırılmış özelliklere sahipseniz (ör. style.background ) belirsiz bir renk değerine ayarlayarak, düşündüğünüzde hata ayıkladığınızdan emin olun.


1

Benim durumumda, LoadingServicebir BehavioralSubject ile zaman uyumsuz bir özellik vardıisLoading

Kullanılması [gizli] modeli işleri ancak * ngIf başarısız

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

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

1

Rxjs kullanarak benim için çalışan bir çözüm

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

sorunlu kod neydi? buradaki çözüm nedir?
mkb

Merhaba @mkb ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.DOM değiştiğinde değer değişiklikleri tetiklendiğinde sorun oluştu
Sandeep K Nair

Merhaba, yani sorunun üstesinden gelmek için burada ne yaptınız. Daha önce hiç rxjs kullanmadınız veya delay () eklediniz veya startWith () eklediniz mi? Zaten çeşitli rxjs yöntemleri ile rxjs kullanın ama yine de hata almak, ben mistery çözmek istiyoruz :(
mkb

Eklenen delayhatayı ortadan kaldırır. Benzer şekilde çalışır setTimeout.
Lazar Ljubenović

1

Ionic3 (teknoloji yığınının bir parçası olarak Angular 4 kullanan) bu tür bir hata vardı.

Benim için bunu yapıyordu:

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

Ben şartlı bir türünü değiştirmeye çalışıyormuş Yani iyon simgesinden bir gelen pinbir etmekremove-circle , bir mod başına ekran üzerinde işletim oldu.

Sanırım *ngIfbunun yerine bir tane eklemek zorunda kalacağım .


1

Eklediğimde sorunum ortaya çıktı *ngIfama nedeni bu değildi. Hata, modeldeki {{}}etiketleri değiştirip *ngIfdaha sonra ifadede değiştirilen modeli görüntülemeye çalışmaktan kaynaklandı . İşte bir örnek:

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

Sorunu çözmek için, aradığım changeMyModelValue()yeri daha mantıklı bir yere değiştirdim .

Benim durumumda, changeMyModelValue()bir alt bileşen verileri her değiştirdiğinde çağırmak istedim . Bu, üst bileşenin üstesinden gelebilmesi için alt bileşende bir olay oluşturmamı ve yayınlamamı gerektirir ( changeMyModelValue()bkz. Https://angular.io/guide/component-interaction#parent-listens-for-child-event


0

Bunun buraya gelmesine yardımcı olacağını umuyorum: Hizmet çağrılarını ngOnInitaşağıdaki şekilde yapıyoruz displayMainve elemanların DOM'a montajını kontrol etmek için bir değişken kullanıyoruz .

component.ts

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

ve component.html

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

0

Bu hatayı aldım, çünkü component.ts içinde bildirilmeyen bir bileşeni component.html dosyasında kullandım. HTML'de parçayı kaldırdığımda, bu hata giderildi.


0

Bu hatayı aldım çünkü modalda redux eylemleri gönderiyordum ve modal o zaman açılmadı. Ben modal bileşen girdi almak eylemleri gönderme. Bu yüzden modalın açıldığından ve eylemlerin dipatched olduğundan emin olmak için setTimeout'u oraya koydum.


0

Bununla mücadele eden herkese. İşte bu hatayı düzgün bir şekilde hata ayıklamanın bir yolu: https://blog.angular-university.io/angular-debugging/

Benim durumumda, gerçekten bu hata * ngIf yerine bu [gizli] kesmek kullanarak kurtuldum ...

Ama sağlanan bağlantı bulmak için bana bir suçlu * ngIf :)

Zevk almak.


hiddenBunun yerine kullanmak ngIfbir hack değildir ve sorunun özünü de ele almaz. Sadece sorunu maskeliyorsun.
Lazar Ljubenović

-2

Çözüm ... hizmetler ve rxjs ... olay yayıcılar ve özellik bağlama hem rxjs kullanın ... sen kendini uygulamak daha iyidir, daha fazla kontrol, hata ayıklaması daha kolay. Olay yayıcıların rxjs kullandığını unutmayın. Basitçe, bir hizmet oluşturun ve gözlemlenebilir bir şekilde, her bir bileşenin gözlemciye abone olmasını sağlayın ve gerektiğinde yeni değer veya değer girin


1
Sadece bu soruya cevap vermekle kalmıyor, aynı zamanda korkunç bir tavsiye. Beyler, lütfen Angular'ın CD hatalarını aldığınız için rxjs'i kendiniz yeniden uygulamayın. :)
Lazar Ljubenović
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.