EkspresiChangedSetelahHasBeenCheckedError Dijelaskan

308

Tolong jelaskan kepada saya mengapa saya terus mendapatkan kesalahan ini: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.

Jelas, saya hanya mendapatkannya dalam mode dev, itu tidak terjadi pada build produksi saya, tapi itu sangat menjengkelkan dan saya tidak mengerti manfaat memiliki kesalahan di lingkungan dev saya yang tidak akan muncul di prod - -mungkin karena kurangnya pemahaman saya.

Biasanya, perbaikannya cukup mudah, saya hanya membungkus kode yang menyebabkan kesalahan dalam setTimeout seperti ini:

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

Atau paksa deteksi perubahan dengan konstruktor seperti ini constructor(private cd: ChangeDetectorRef) {}::

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

Tetapi mengapa saya terus-menerus mengalami kesalahan ini? Saya ingin memahaminya sehingga saya dapat menghindari perbaikan yang tidak rapi ini di masa depan.

Kevin LeStarge
sumber
11
Segala sesuatu yang perlu Anda ketahui tentang EkspresiDirubahSetelahHasBeenCheckedError error menjelaskan perilaku ini dengan sangat rinci
Max Koretskyi

Jawaban:

121

Saya punya masalah serupa. Melihat dokumentasi siklus hidup kait , aku berubah ngAfterViewInituntuk ngAfterContentInitdan bekerja.

hanya saya
sumber
@ PhilipEnc masalah saya terkait dengan perubahan yang dipicu oleh perubahan DOM. Ketika DOM akan berubah, objek QueryList (yang berasal dari properti @ContentChildren) akan memperbarui, dan di dalam metode yang disebut pembaruan itu mengubah properti terikat dua arah. Ini menciptakan masalah yang saya alami. Membungkus perubahan itu ke dua properti dengan setTimeoutseperti yang Anda tunjukkan di atas berhasil. Terima kasih!
kbpontius
1
Dalam kasus saya, saya telah menempatkan beberapa kode yang mengubah nilai array grid primeng di ngAfterContentInit, saya menempatkan kode di ngOnInit dan berhasil.
Vibhu
ngAfterContentCheckedbekerja di sini sementara ngAfterContentInitmasih melempar kesalahan.
ashubuntu
ngAfterContentChecked digunakan tetapi proyek dimuat sangat lambat
Ghotekar Rahul
101

Kesalahan ini menunjukkan masalah nyata dalam aplikasi Anda, oleh karena itu masuk akal untuk melemparkan pengecualian.

Dalam devModedeteksi perubahan tambahkan giliran tambahan setelah setiap deteksi perubahan reguler dijalankan untuk memeriksa apakah model telah berubah.

Jika model telah berubah antara perubahan deteksi perubahan reguler dan tambahan, ini menunjukkan bahwa baik

  • perubahan deteksi itu sendiri telah menyebabkan perubahan
  • metode atau pengambil mengembalikan nilai yang berbeda setiap kali dipanggil

yang keduanya buruk, karena tidak jelas bagaimana melanjutkan karena modelnya mungkin tidak pernah stabil.

Jika Angular menjalankan deteksi perubahan hingga model stabil, mungkin akan berjalan selamanya. Jika Angular tidak menjalankan deteksi perubahan, maka tampilan mungkin tidak mencerminkan keadaan model saat ini.

Lihat juga Apa perbedaan antara mode produksi dan pengembangan di Angular2?

Günter Zöchbauer
sumber
4
Bagaimana saya bisa menghindari melihat kesalahan ini di masa depan? Apakah ada cara berbeda yang perlu saya pikirkan tentang kode saya untuk memastikan saya tidak melakukan kesalahan yang sama?
Kevin LeStarge
25
Biasanya ini disebabkan oleh beberapa callback daur ulang seperti ngOnInitatau ngOnChangesuntuk memodifikasi model (beberapa panggilan balik siklus memungkinkan memodifikasi model yang lain tidak, saya tidak ingat sendiri persis mana yang melakukan atau tidak). Jangan mengikat metode atau fungsi dalam tampilan, melainkan mengikat ke bidang dan memperbarui bidang dalam penangan acara. Jika Anda harus mengikat ke metode, pastikan bahwa mereka selalu mengembalikan contoh nilai yang sama selama tidak ada perubahan. Deteksi perubahan akan memanggil metode ini banyak.
Günter Zöchbauer
Bagi siapa pun yang datang ke sini yang mendapatkan kesalahan ini menggunakan perpustakaan ngx-toaster, berikut adalah laporan bug: github.com/scttcper/ngx-toastr/issues/160
rmcsharry
2
Itu tidak selalu masalah dengan aplikasi. Fakta bahwa menelepon changeRef.detectChanges()adalah solusi / menekan kesalahan, adalah buktinya. Ini seperti memodifikasi keadaan di $scope.$watch()dalam Angular 1.
Kevin Beal
1
Saya tidak tahu Angular 1 terlalu baik tetapi deteksi perubahan di Angular 2 bekerja sangat berbeda. Anda benar bahwa itu tidak selalu menjadi masalah, tetapi biasanya cdRef.detectChanges()hanya diperlukan dalam beberapa kasus tepi yang aneh dan Anda harus melihat dengan hati-hati ketika Anda membutuhkannya sehingga Anda mengerti mengapa.
Günter Zöchbauer
83

Banyak pengertian muncul begitu saya memahami Angular Lifecycle Hooks dan hubungannya dengan deteksi perubahan.

Saya mencoba membuat Angular memperbarui bendera global yang terikat pada *ngIfelemen, dan saya mencoba mengubah bendera itu di dalam ngOnInit()kait siklus hidup komponen lain.

Menurut dokumentasi, metode ini dipanggil setelah Angular mendeteksi perubahan:

Disebut sekali, setelah ngOnChanges pertama ().

Jadi memperbarui bendera di dalamnya ngOnChanges()tidak akan memulai deteksi perubahan. Kemudian, begitu deteksi perubahan dipicu secara alami lagi, nilai bendera telah berubah dan kesalahan dilemparkan.

Dalam kasus saya, saya mengubah ini:

constructor(private globalEventsService: GlobalEventsService) {

}

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

Untuk ini:

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

ngOnInit() {

}

dan itu memperbaiki masalah :)

Kevin LeStarge
sumber
3
Masalah saya serupa. Bahwa saya melakukan kesalahan setelah berjam-jam, dan mendefinisikan variabel di luar fungsi dan konstruktor ngOnInit. Ini menerima perubahan data dari yang dapat diamati, yang ditempatkan dalam fungsi inisialisasi. Lakukan hal yang sama seperti Anda untuk memperbaiki kesalahan.
ravo10
1
Sangat mirip di sekitar, tetapi saya mencoba untuk menggulir ( router.navigate) saat memuat ke sebuah fragmen jika ada di URL. Kode ini awalnya ditempatkan di AfterViewInittempat saya menerima kesalahan, kemudian saya pindah seperti yang Anda katakan kepada konstruktor tetapi tidak menghormati fragmen. Pindah ke ngOnInitdiselesaikan :) terima kasih!
Joel Balmer
Bagaimana jika html saya terikat dengan waktu pengembalian pengambil sebagai "HH: MM" melalui get ClockValue () {return DateTime.TimeAMPM (Date baru ())} pada akhirnya akan trip ketika menit berubah saat deteksi berjalan, bagaimana saya bisa Perbaiki ini?
Meryan
Sama disini. Juga menemukan bahwa membungkus ke dalam setInterval()karya juga jika perlu memecat kode acara seumur hidup lainnya.
Rick Strahl
39

Memperbarui

Saya sangat merekomendasikan memulai dengan respons diri OP terlebih dahulu: pikirkan dengan benar tentang apa yang bisa dilakukan dalam constructorvs apa yang harus dilakukan ngOnChanges().

Asli

Ini lebih merupakan catatan samping daripada jawaban, tetapi mungkin membantu seseorang. Saya menemukan masalah ini ketika mencoba membuat keberadaan tombol tergantung pada kondisi formulir:

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

Sejauh yang saya tahu, sintaks ini mengarah ke tombol yang ditambahkan dan dihapus dari DOM berdasarkan kondisi. Yang pada gilirannya mengarah pada ExpressionChangedAfterItHasBeenCheckedError.

Perbaikan dalam kasus saya (meskipun saya tidak mengklaim memahami implikasi penuh dari perbedaan), adalah display: nonesebagai gantinya digunakan :

<button [style.display]="form.pristine ? 'inline' : 'none'">Yo</button>
Arnaud P
sumber
6
Pemahaman saya tentang perbedaan antara ngIf vs gaya adalah bahwa ngIf tidak menyertakan HTML dalam halaman sampai kondisinya benar, sehingga mengurangi "berat halaman" sedikit saja, sedangkan teknik gaya menyebabkan HTML selalu menjadi di halaman dan hanya disembunyikan atau ditampilkan berdasarkan nilai form.pristine.
user3785010
4
Anda sebaiknya menggunakan [hidden]bukan bagian yang sangat bertele-tele [style.display]. :)
Philipp Meissner
2
Kenapa tidak. Meskipun, seperti yang disebutkan oleh @Simon_Weaver dalam komentar lain di halaman ini, [hidden] tidak akan selalu memiliki perilaku yang sama sepertidisplay: none
Arnaud P
1
Saya menunjukkan dua tombol berbeda (logout / login) dengan * ngIf di setiap tombol dan ini menyebabkan masalah.
GoTo
konstruktor adalah tempat yang tepat bagi saya, meluncurkan bahan makanan ringan
austin
31

Ada jawaban yang menarik tetapi saya sepertinya tidak menemukan satu yang cocok dengan kebutuhan saya, yang terdekat dari @ chittrang-mishra yang hanya merujuk pada satu fungsi tertentu dan tidak beberapa toggle seperti pada aplikasi saya.

Saya tidak ingin menggunakan [hidden]untuk mengambil keuntungan dari *ngIftidak menjadi bagian dari DOM, jadi saya menemukan solusi berikut yang mungkin bukan yang terbaik untuk semua karena menekan kesalahan daripada memperbaikinya, tetapi dalam kasus saya di mana saya tahu hasil akhirnya sudah benar, sepertinya ok untuk aplikasi saya.

Apa yang saya lakukan adalah mengimplementasikan AfterViewChecked, menambah constructor(private changeDetector : ChangeDetectorRef ) {}dan kemudian

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

Saya harap ini membantu yang lain karena banyak yang telah membantu saya.

eper
sumber
3
bukankah ini akan memicu loop deteksi perubahan tak terbatas? maksud saya, Anda mendeteksi perubahan setelah Anda memeriksa.
Manuel Azar
@ManuelAzar Ternyata tidak. Ini adalah solusi HANYA yang bekerja untuk saya. SETIDAKNYA sedikit keheningan di konsol saya. Saya sangat lelah dengan semua "deteksi" deteksi perubahan yang tidak relevan ini.
Jeremy Thille
31

Angular menjalankan perubahan deteksi dan ketika menemukan bahwa beberapa nilai yang telah diteruskan ke komponen anak telah diubah Angular melempar kesalahan:

ExpressionChangedAfterItHasBeenCheckedError klik untuk lebih

Untuk memperbaikinya kita dapat menggunakan AfterContentCheckedkait siklus hidup dan

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

  constructor(
  private cdref: ChangeDetectorRef) { }

  ngAfterContentChecked() {

    this.cdref.detectChanges();

  }
Lijo
sumber
Meskipun ini dapat memperbaiki masalah, bukankah ini terlalu ekspansif dan berlebihan pada CD?
Nicky
Saya pikir ini adalah satu-satunya jawaban yang mengatasi kesalahan ini yang disebabkan oleh memberikan nilai kepada seorang anak. Terima kasih!
java-addict301
@Nicky Ya. Setiap kali Anda menyentuh layar, di mana saja, ngAfterContentChecked () disebut
Mert Mertce
25

Dalam kasus saya, saya memiliki masalah ini di file spesifikasi saya, saat menjalankan tes saya.

Saya harus pindah ngIf ke [hidden]

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

untuk

<app-loading [hidden]="!isLoading"></app-loading>
Andre Evangelista
sumber
2
Perbedaannya di sini adalah bahwa *ngIfmengubah DOM, menambah dan menghapus elemen dari halaman, sementara [hidden]mengubah visibilitas item sambil tidak menghapusnya dari DOM.
Grungondola
5
Tapi, ini tidak benar-benar memperbaiki masalah sebenarnya ...?
ravo10
23

Ikuti langkah-langkah di bawah ini:

1. Gunakan 'ChangeDetectorRef' dengan mengimpornya dari @ angular / core sebagai berikut:

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

2. Terapkan dalam constructor () sebagai berikut:

constructor(   private cdRef : ChangeDetectorRef  ) {}

3. Tambahkan metode berikut ke fungsi Anda yang Anda panggil pada suatu acara seperti klik tombol. Jadi terlihat seperti ini:

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

Saya menggunakan ng2-carouselamos (Angular 8 & Bootstrap 4)

Di bawah ini memperbaiki masalah saya:

Apa yang saya lakukan:

1. implement AfterViewChecked,  
2. add constructor(private changeDetector : ChangeDetectorRef ) {} and then 
3. ngAfterViewChecked(){ this.changeDetector.detectChanges(); }
Shahid Hussain Abbasi
sumber
Itu membantu. Luar biasa !!
Pathik Vejani
Anda menyelamatkan hari saya ... Terima kasih!
omostan
19

Saya menghadapi masalah yang sama ketika nilai berubah di salah satu array di komponen saya. Tetapi alih-alih mendeteksi perubahan pada perubahan nilai, saya mengubah strategi deteksi perubahan komponen menjadi onPush(yang akan mendeteksi perubahan pada perubahan objek dan bukan pada perubahan nilai).

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

@Component({
    changeDetection: ChangeDetectionStrategy.OnPush
    selector: -
    ......
})
Dheeraj
sumber
Ini sepertinya berfungsi untuk menambah / menghapus dari kontrol secara dinamis .. apakah ada kekurangan?
Ricardo Saracino
Bekerja seperti pesona dalam situasi yang saya miliki, terima kasih! Komponen terikat ke objek "global" yang diubah di tempat lain dan menyebabkan Kesalahan terjadi. Komponen ini sudah memiliki handler pembaruan ketika objek terikat diperbarui, handler event ini sekarang memanggil changeDetectorRef.detectChanges () bersama dengan ChangeDetectionStrategy.OnPush ini berfungsi seperti yang diinginkan tanpa kesalahan.
Bernoulli IT
@RicardoSaracino apakah Anda menemukan kekurangan? Saya bertanya-tanya hal yang sama. Saya tahu cara kerja deteksi deteksi OnPush, tetapi bertanya-tanya apakah ada gotcha yang mungkin saya lewatkan. Saya tidak ingin harus berputar kembali.
mtpultz
@RicardoSaracino, Ya ada beberapa kekurangan, Anda dapat merujuk tautan blog yang
Dheeraj
@BernoulliIT Terima kasih, saya senang itu berhasil untuk Anda.
Dheeraj
17

Mengacu pada artikel https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeeckeckederror-error-e3fd9ce7dbb4

Jadi mekanisme di balik deteksi perubahan benar-benar bekerja sedemikian rupa sehingga kedua deteksi perubahan dan pengujian dicerna secara serempak. Itu berarti, jika kita memperbarui properti secara tidak sinkron, nilai-nilai tidak akan diperbarui ketika loop verifikasi sedang berjalan dan kami tidak akan mendapatkan ExpressionChanged...kesalahan. Alasan kami mendapatkan kesalahan ini adalah, selama proses verifikasi, Angular melihat nilai yang berbeda dari yang dicatat selama fase deteksi deteksi. Jadi untuk menghindari itu ....

1) Gunakan changeDetectorRef

2) gunakan setTimeOut. Ini akan mengeksekusi kode Anda di VM lain sebagai tugas makro. Angular tidak akan melihat perubahan ini selama proses verifikasi dan Anda tidak akan mendapatkan kesalahan itu.

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

3) Jika Anda benar-benar ingin mengeksekusi kode Anda pada penggunaan VM yang sama seperti

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

Ini akan membuat tugas mikro. Antrian tugas mikro diproses setelah kode sinkron saat ini selesai dieksekusi sehingga pembaruan ke properti akan terjadi setelah langkah verifikasi.

ATHER
sumber
Bisakah Anda menggunakan opsi # 3 dengan ekspresi gaya? Saya memiliki ekspresi gaya untuk ketinggian yang harus dievaluasi terakhir, karena didasarkan pada konten yang disuntikkan.
N-makan
1
Maaf hanya melihat komentar Anda, ya saya tidak melihat alasan mengapa tidak. Jadi itu harus bekerja dengan perubahan gaya juga.
ATHER
4

@HostBinding dapat menjadi sumber kesalahan yang membingungkan ini.

Sebagai contoh, katakanlah Anda memiliki host berikut yang mengikat komponen

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

Untuk mempermudah, katakanlah properti ini diperbarui melalui properti input berikut:

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

Di komponen induk Anda secara sistematis memasukkannya ngAfterViewInit

@ViewChild(ImageCarousel) carousel: ImageCarousel;

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

Inilah yang terjadi:

  • Komponen induk Anda dibuat
  • Komponen ImageCarousel dibuat, dan ditugaskan untuk carousel (melalui ViewChild)
  • Kami tidak dapat mengakses carouselsampaingAfterViewInit() (itu akan menjadi nol)
  • Kami menetapkan konfigurasi, yang ditetapkan style_groupBG = 'red'
  • Ini pada gilirannya mengatur background: red pada komponen ImageCarousel host
  • Komponen ini 'dimiliki' oleh komponen induk Anda, jadi ketika memeriksa perubahan, ia menemukan perubahan carousel.style.backgrounddan tidak cukup pandai untuk mengetahui bahwa ini bukan masalah sehingga membuang pengecualian.

Salah satu solusinya adalah dengan memperkenalkan ImageCarousel pembungkus div insider lain dan mengatur warna latar belakangnya, tetapi kemudian Anda tidak mendapatkan beberapa manfaat menggunakan HostBinding(seperti memungkinkan orang tua untuk mengontrol batas penuh objek).

Solusi yang lebih baik, dalam komponen induk adalah menambahkan detectChanges () setelah pengaturan konfigurasi.

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

Ini mungkin terlihat cukup jelas seperti ini, dan sangat mirip dengan jawaban lain tetapi ada perbedaan yang halus.

Pertimbangkan kasus di mana Anda tidak menambahkan @HostBindingsampai nanti selama pengembangan. Tiba-tiba Anda mendapatkan kesalahan ini dan sepertinya tidak masuk akal.

Simon_Weaver
sumber
2

Inilah pemikiran saya tentang apa yang terjadi. Saya belum membaca dokumentasi tetapi saya yakin ini adalah bagian dari mengapa kesalahan ditampilkan.

*ngIf="isProcessing()" 

Saat menggunakan * ngIf, secara fisik mengubah DOM dengan menambahkan atau menghapus elemen setiap kali kondisinya berubah. Jadi, jika kondisi berubah sebelum ditampilkan (yang sangat mungkin di dunia Angular), kesalahan dilemparkan. Lihat penjelasan di sini antara mode pengembangan dan produksi.

[hidden]="isProcessing()"

Saat menggunakannya [hidden]tidak secara fisik mengubah DOMtetapi hanya menyembunyikan elementdari tampilan, kemungkinan besar menggunakan CSSdi belakang. Elemen tersebut masih ada di DOM tetapi tidak terlihat tergantung pada nilai kondisinya. Itu sebabnya kesalahan tidak akan terjadi saat menggunakan [hidden].

Kobus
sumber
Jika isProcessing()melakukan hal yang sama, Anda harus menggunakan !isProcessing()untuk[hidden]
Matthieu Charbonnier
hiddentidak "menggunakan CSS di belakang", ini adalah properti HTML biasa. developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/…
Lazar Ljubenović
1

Untuk masalah saya, saya membaca github - "ExpressionChangedAfterItHasBeenCheckedError ketika mengubah nilai komponen 'non model' di afterViewInit" dan memutuskan untuk menambahkan ngModel

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

Ini memperbaiki masalah saya, saya harap ini membantu seseorang.

Demodave
sumber
1
Di mana di situs itu katanya menambahkan ngModel. Dan bisakah Anda menjelaskan mengapa ini harus membantu?
Peter Wippermann
Ketika saya melacak masalah ini, itu mengarahkan saya untuk menyelidiki tautan. Setelah membaca artikel saya menambahkan atribut dan itu memperbaiki masalah saya. Akan sangat membantu jika seseorang mengalami masalah yang sama.
Demodave
1

Kiat debugging

Kesalahan ini bisa sangat membingungkan, dan mudah untuk membuat asumsi yang salah tentang kapan tepatnya itu terjadi. Saya merasa bermanfaat untuk menambahkan banyak pernyataan debugging seperti ini di seluruh komponen yang terkena dampak di tempat yang tepat. Ini membantu memahami aliran.

Dalam induk, letakkan pernyataan seperti ini (string persis 'EXPRESSIONCHANGED' penting), tetapi selain itu, ini hanya contoh:

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

Dalam panggilan balik anak / layanan / timer:

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

Jika Anda menjalankan detectChangessecara manual tambahkan logging untuk itu juga:

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

Kemudian di Chrome debugger cukup filter dengan 'EXPRESSIONCHANGES'. Ini akan menunjukkan Anda dengan tepat aliran dan urutan semua yang diatur, dan juga tepat pada titik mana Angular melempar kesalahan.

masukkan deskripsi gambar di sini

Anda juga dapat mengklik tautan abu-abu untuk memasukkan breakpoints.

Hal lain yang harus diperhatikan jika Anda memiliki properti dengan nama yang sama di seluruh aplikasi Anda (seperti style.background) pastikan Anda mendebug yang menurut Anda - dengan mengaturnya ke nilai warna yang tidak jelas.

Simon_Weaver
sumber
1

Dalam kasus saya, saya memiliki properti async LoadingServicedengan BehavioralSubjectisLoading

Menggunakan model [tersembunyi] berfungsi, tetapi * ngIf gagal

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

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

Solusi yang bekerja untuk saya menggunakan 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();
}
Sandeep K. Nair
sumber
apa kode yang bermasalah? apa solusinya di sini?
mkb
Hai @ mkb masalah ini ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked.Terjadi ketika perubahan nilai dipicu ketika DOM berubah
Sandeep K Nair
Hai, maksud saya apa yang Anda lakukan di sini untuk mengatasi masalah tersebut. Anda tidak menggunakan rxjs sama sekali sebelumnya atau menambahkan penundaan (), atau menambahkan startWith ()? Saya sudah menggunakan rxjs dengan berbagai metode rxjs tetapi masih mendapatkan kesalahan, saya berharap dapat memecahkan misteri :(
mkb
Yang ditambahkan delaymembuat kesalahan hilang. Ini bekerja sama dengan setTimeout.
Lazar Ljubenović
1

Saya memiliki kesalahan semacam ini di Ionic3 (yang menggunakan Angular 4 sebagai bagian dari tumpukan teknologinya).

Bagi saya itu melakukan ini:

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

Jadi saya mencoba mengubah jenis ikon ion dari a pinmenjadi aremove-circle , per mode yang dioperasikan layar.

Saya kira saya harus menambahkan *ngIfsaja.

JGFMK
sumber
1

Masalah saya nyata ketika saya menambahkan *ngIftetapi itu bukan penyebabnya. Kesalahan itu disebabkan oleh mengubah model dalam {{}}tag kemudian mencoba menampilkan model yang diubah dalam *ngIfpernyataan di kemudian hari. Ini sebuah contoh:

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

Untuk memperbaiki masalah ini, saya mengubah tempat saya memanggil changeMyModelValue()ke tempat yang lebih masuk akal.

Dalam situasi saya, saya ingin changeMyModelValue()dipanggil setiap kali komponen anak mengubah data. Ini mengharuskan saya membuat dan memancarkan suatu peristiwa dalam komponen anak sehingga orang tua dapat menanganinya (dengan menelepon changeMyModelValue(). Lihat https://angular.io/guide/component-interaction#parent-listens-for-child-event

goku_da_master
sumber
0

Saya harap ini membantu seseorang yang datang ke sini: Kami melakukan panggilan layanan ngOnInitdengan cara berikut dan menggunakan variabel displayMainuntuk mengontrol Pemasangan elemen ke DOM.

komponen.ts

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

dan component.html

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

Saya mendapatkan kesalahan ini karena saya menggunakan variabel di component.html yang tidak dideklarasikan di component.ts. Setelah saya menghapus bagian dalam HTML, kesalahan ini hilang.

shreekar hegde
sumber
0

Saya mendapatkan kesalahan ini karena saya mengirim tindakan redux dalam modal dan modal tidak dibuka pada waktu itu. Saya mengirim tindakan saat input komponen modal saat. Jadi saya meletakkan setTimeout di sana untuk memastikan bahwa modal dibuka dan kemudian tindakan dipatched.

Muneem Habib
sumber
0

Untuk siapa pun yang berjuang dengan ini. Inilah cara untuk men-debug kesalahan ini dengan benar: https://blog.angular-university.io/angular-debugging/

Dalam kasus saya, memang saya menyingkirkan kesalahan ini menggunakan hack [tersembunyi] ini daripada * ngIf ...

Tapi tautan yang saya berikan memungkinkan saya menemukan THE GUILTY * ngIf :)

Nikmati.

Deunz
sumber
Menggunakan hiddenalih-alih ngIfbukanlah meretas, juga tidak membahas inti masalah sama sekali. Anda hanya menutupi masalah itu.
Lazar Ljubenović
-2

Solusinya ... layanan dan rxjs ... emitor acara dan pengikatan properti baik menggunakan rxjs .. Anda lebih baik menerapkannya sendiri, lebih banyak kontrol, lebih mudah untuk debug. Ingatlah bahwa emitor acara menggunakan rxjs. Sederhananya, buat layanan dan dengan cara yang dapat diamati, mintalah setiap komponen berlangganan pengamat dan berikan nilai baru atau nilai cosume sesuai kebutuhan

pengguna998548
sumber
1
Tidak hanya ini tidak menjawab pertanyaan, itu juga saran yang mengerikan. Kawan, tolong jangan laksanakan ulang rxjs sendiri hanya karena Anda mendapatkan kesalahan CD Angular. :)
Lazar Ljubenović