Dia Anda pergi dua solusi!
1. Ubah ChangeDetectionStrategy ke OnPush
Untuk solusi ini, Anda pada dasarnya memberi tahu sudut:
Berhenti memeriksa perubahan; Saya akan melakukannya hanya jika saya tahu itu perlu
Perbaikan cepat:
Ubah komponen Anda sehingga akan digunakan ChangeDetectionStrategy.OnPush
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent implements OnInit {
// ...
}
Dengan ini, semuanya sepertinya tidak berfungsi lagi. Itu karena mulai sekarang Anda harus membuat panggilan Angular detectChanges()
secara manual.
this.cdr.detectChanges();
Berikut ini tautan yang membantu saya memahami ChangeDetectionStrategy benar:
https://alligator.io/angular/change-detection-strategy/
2. Memahami Ekspresi yang DiubahSetelahMemilikiBeenTidak Teror
Berikut ini adalah ekstrak kecil dari jawaban tomonari_t tentang penyebab kesalahan ini, saya hanya mencoba memasukkan bagian-bagian yang membantu saya untuk memahami hal ini.
Artikel lengkap menunjukkan contoh kode nyata tentang setiap titik yang ditampilkan di sini.
Penyebab dasarnya adalah siklus hidup sudut:
Setelah setiap operasi, Angular ingat nilai apa yang digunakannya untuk melakukan operasi. Mereka disimpan di properti oldValues dari tampilan komponen.
Setelah pemeriksaan dilakukan untuk semua komponen, Angular kemudian memulai siklus intisari berikutnya, tetapi alih-alih melakukan operasi, ia membandingkan nilai saat ini dengan yang ia ingat dari siklus intisari sebelumnya.
Operasi berikut sedang diperiksa pada siklus digest:
periksa bahwa nilai yang diturunkan ke komponen turunan sama dengan nilai yang akan digunakan untuk memperbarui properti komponen ini sekarang.
periksa bahwa nilai yang digunakan untuk memperbarui elemen DOM sama dengan nilai yang akan digunakan untuk memperbarui elemen ini sekarang melakukan hal yang sama.
memeriksa semua komponen anak
Jadi, kesalahan dilemparkan ketika nilai yang dibandingkan berbeda. , blogger Max Koretskyi menyatakan:
Pelakunya selalu merupakan komponen anak atau arahan.
Dan akhirnya, inilah beberapa contoh dunia nyata yang biasanya menyebabkan kesalahan ini:
- Layanan berbagi
- Siaran acara sinkron
- Instansiasi komponen dinamis
Setiap sampel dapat ditemukan di sini (plunkr), dalam kasus saya masalahnya adalah instantiasi komponen dinamis.
Juga, berdasarkan pengalaman saya sendiri, saya sangat menyarankan semua orang untuk menghindari setTimeout
solusi, dalam kasus saya menyebabkan loop "hampir" tak terbatas (21 panggilan yang saya tidak mau tunjukkan kepada Anda bagaimana memprovokasi mereka),
Saya akan merekomendasikan untuk selalu mengingat siklus hidup Angular sehingga Anda dapat memperhitungkan bagaimana mereka akan terpengaruh setiap kali Anda mengubah nilai komponen lain. Dengan kesalahan ini, Angular memberi tahu Anda:
Anda mungkin melakukan ini dengan cara yang salah, apakah Anda yakin Anda benar?
Blog yang sama juga mengatakan:
Seringkali, perbaikannya adalah dengan menggunakan kait deteksi perubahan yang tepat untuk membuat komponen dinamis
Panduan singkat bagi saya adalah untuk mempertimbangkan setidaknya dua hal berikut ini saat coding ( saya akan mencoba melengkapinya dari waktu ke waktu ):
- Hindari mengubah nilai komponen induk dari komponen turunannya, sebagai gantinya: modifikasi dari induknya.
- Ketika Anda menggunakan
@Input
dan @Output
arahan, cobalah untuk menghindari memicu perubahan siklus lyf kecuali komponen sepenuhnya diinisialisasi.
- Hindari panggilan yang tidak perlu
this.cdr.detectChanges();
karena dapat memicu lebih banyak kesalahan, khususnya ketika Anda berurusan dengan banyak data dinamis
- Ketika penggunaan
this.cdr.detectChanges();
wajib, pastikan bahwa variabel ( @Input, @Output, etc
) yang digunakan diisi / diinisialisasi pada kait deteksi kanan ( OnInit, OnChanges, AfterView, etc
)
- Jika memungkinkan, hapus alih-alih sembunyikan , ini terkait dengan poin 3 dan 4.
Juga
Jika Anda ingin sepenuhnya memahami Angular Life Hook, saya sarankan Anda untuk membaca dokumentasi resmi di sini: