Apa perbedaan antara ChangeDetectorRef.markForCheck()
dan ChangeDetectorRef.detectChanges()
?
Saya hanya menemukan informasi tentang perbedaan antara SONgZone.run()
, tetapi tidak antara dua fungsi ini.
Untuk jawaban dengan hanya referensi ke dokumen, harap ilustrasikan beberapa skenario praktis untuk memilih satu dari yang lain.
angular
angular2-changedetection
parlemen
sumber
sumber
Jawaban:
Dari dokumen:
Itu berarti, jika ada kasus di mana sesuatu di dalam model Anda (kelas Anda) telah berubah tetapi itu tidak mencerminkan tampilan, Anda mungkin perlu memberi tahu Angular untuk mendeteksi perubahan tersebut (mendeteksi perubahan lokal) dan memperbarui tampilan.
Skenario yang mungkin:
1- Detektor perubahan dilepaskan dari pandangan (lihat melepaskan )
2- Pembaruan telah terjadi tetapi belum ada di dalam Zona Angular, oleh karena itu, Angular tidak mengetahuinya.
Seperti ketika fungsi pihak ketiga memperbarui model Anda dan Anda ingin memperbarui tampilan setelah itu.
Karena kode ini berada di luar zona Angular (mungkin), kemungkinan besar Anda perlu memastikan untuk mendeteksi perubahan dan memperbarui tampilan, dengan demikian:
CATATAN :
Ada cara lain untuk membuat pekerjaan di atas, dengan kata lain, ada cara lain untuk membawa perubahan itu dalam siklus perubahan sudut.
** Anda bisa membungkus fungsi pihak ketiga itu di dalam zone.run:
** Anda bisa membungkus fungsi di dalam setTimeout:
3 - Ada juga kasus di mana Anda memperbarui model setelah
change detection cycle
selesai, di mana dalam kasus tersebut Anda mendapatkan kesalahan yang ditakuti ini:"Ekspresi telah berubah setelah diperiksa";
Ini umumnya berarti (dari bahasa Angular2):
Saya melihat perubahan pada model Anda yang disebabkan oleh salah satu cara saya yang diterima (peristiwa, permintaan XHR, setTimeout, dan ...) dan kemudian saya menjalankan deteksi perubahan untuk memperbarui tampilan Anda dan saya menyelesaikannya, tetapi kemudian ada lagi berfungsi dalam kode Anda yang memperbarui model lagi dan saya tidak ingin menjalankan deteksi perubahan saya lagi karena tidak ada pemeriksaan kotor seperti AngularJS lagi: D dan kita harus menggunakan aliran data satu arah!
Anda pasti akan menemukan kesalahan ini: P.
Beberapa cara untuk memperbaikinya:
1- Cara yang benar : pastikan pembaruan ada di dalam siklus deteksi perubahan (Pembaruan Angular2 adalah salah satu cara yang terjadi sekali, jangan perbarui model setelah itu dan pindahkan kode Anda ke tempat / waktu yang lebih baik).
2- Cara malas : jalankan detectChanges () setelah pembaruan itu untuk membuat angular2 bahagia, ini jelas bukan cara terbaik, tetapi ketika Anda bertanya skenario apa yang mungkin terjadi, ini adalah salah satunya.
Dengan cara ini Anda mengatakan: Saya sungguh-sungguh tahu Anda menjalankan deteksi perubahan, tetapi saya ingin Anda melakukannya lagi karena saya harus memperbarui sesuatu dengan cepat setelah Anda selesai memeriksa.
3 - Masukkan kode di dalam
setTimeout
, karenasetTimeout
ditambal oleh zona dan akan berjalandetectChanges
setelah selesai.Dari dokumen
Ini sebagian besar diperlukan ketika ChangeDetectionStrategy komponen Anda adalah OnPush .
OnPush sendiri berarti, hanya menjalankan deteksi perubahan jika salah satu dari ini terjadi:
1- Salah satu input @ komponen telah sepenuhnya diganti dengan nilai baru, atau cukup cantumkan, jika referensi properti @ Input telah berubah sama sekali.
Jadi jika ChangeDetectionStrategy dari komponen Anda adalah OnPush dan Anda memiliki:
Dan kemudian Anda memperbarui / bermutasi seperti:
Ini tidak akan memperbarui obj referensi, maka deteksi perubahan tidak akan lari, karena pandangan tidak mencerminkan update / mutasi.
Dalam hal ini Anda harus memberi tahu Angular secara manual untuk memeriksa dan memperbarui tampilan (markForCheck);
Jadi, jika Anda melakukan ini:
Anda perlu melakukan ini:
Sebaliknya, di bawah ini akan menyebabkan deteksi perubahan berjalan:
Yang sepenuhnya menggantikan objek sebelumnya dengan yang baru
{}
;2- Suatu peristiwa telah dipecat, seperti klik atau sesuatu seperti itu atau komponen anak mana saja yang telah memancarkan suatu peristiwa.
Acara seperti:
Singkatnya:
Gunakan
detectChanges()
saat Anda memperbarui model setelah sudut menjalankan deteksi perubahan, atau jika pembaruan belum ada di dunia sudut sama sekali.Gunakan
markForCheck()
jika Anda menggunakan OnPush dan Anda mem-bypassChangeDetectionStrategy
dengan mematikan beberapa data atau Anda telah memperbarui model di dalam setTimeout ;sumber
detectChanges
tampilan pembaruan. Lihat penjelasan mendalam ini .this.cdMode === ChangeDetectorStatus.Checked
itu tidak akan memperbarui tampilan, itu sebabnya Anda akan menggunakan markForCheck.detectChanges
. Dan tidak adacdMode
dalam Angular4.x.x
. Saya menulis tentang itu di artikel saya. Senang kamu menyukainya. Jangan lupa, Anda dapat merekomendasikannya pada media atau ikuti saya :)Perbedaan terbesar antara keduanya adalah yang
detectChanges()
sebenarnya memicu deteksi perubahan, sementaramarkForCheck()
tidak memicu deteksi perubahan.mendeteksi perubahan
Yang ini digunakan untuk menjalankan deteksi perubahan untuk pohon komponen yang dimulai dengan komponen yang Anda picu
detectChanges()
. Jadi deteksi perubahan akan berjalan untuk komponen saat ini dan semua anak-anaknya. Sudut memegang referensi ke pohon komponen root diApplicationRef
dan ketika operasi async terjadi itu memicu deteksi perubahan pada komponen root ini melalui metode pembungkustick()
:view
di sini adalah tampilan komponen root. Mungkin ada banyak komponen root seperti yang saya jelaskan di Apa implikasi dari beberapa komponen bootstrap .@milad menjelaskan alasan mengapa Anda berpotensi perlu memicu deteksi perubahan secara manual.
tandaiCheck
Seperti yang saya katakan, orang ini sama sekali tidak memicu deteksi perubahan. Itu hanya naik dari komponen saat ini ke komponen root dan memperbarui status tampilan mereka
ChecksEnabled
. Ini kode sumbernya:Deteksi perubahan aktual untuk komponen tidak dijadwalkan tetapi ketika akan terjadi di masa mendatang (baik sebagai bagian dari siklus CD saat ini atau berikutnya) tampilan komponen induk akan diperiksa bahkan jika mereka telah melepaskan detektor perubahan. Detektor perubahan dapat dilepaskan dengan menggunakan
cd.detach()
atau dengan menentukanOnPush
strategi deteksi perubahan. Semua penangan acara asli menandai semua tampilan komponen induk untuk diperiksa.Pendekatan ini sering digunakan dalam
ngDoCheck
kait siklus hidup. Anda dapat membaca lebih lanjut di bagian Jika Anda merasangDoCheck
komponen Anda sedang diperiksa - baca artikel ini .Lihat juga Semua yang perlu Anda ketahui tentang deteksi perubahan di Angular untuk detail lebih lanjut.
sumber
markForCheck
. Jadi jika Anda tidak menggunakan pipa async, mungkin itulah yang harus Anda gunakan. Namun, perlu diingat, bahwa pembaruan toko harus terjadi sebagai akibat dari beberapa peristiwa async untuk memulai deteksi perubahan. Itulah yang selalu terjadi. Tetapi ada pengecualian blog.angularindepth.com/…async pipe
karena di dalam berlangganan kita biasanya memiliki beberapa hal yang harus dilakukan seperticall setFromValues
do some comparison
.. dan jikaasync
itu sendiri memanggilmarkForCheck
apa masalahnya jika kita menyebutnya sendiri? tetapi sekali lagi kami biasanya memiliki 2-3 atau kadang-kadang lebih banyak penyeleksi dalamngOnInit
mendapatkan data yang berbeda ... dan kami memanggilmarkForCheck
semuanya .. apakah itu OK?cd.detectChanges()
akan menjalankan deteksi perubahan segera dari komponen saat ini turun melalui turunannya.cd.markForCheck()
tidak akan menjalankan deteksi perubahan, tetapi menandai leluhurnya sebagai perlu menjalankan deteksi perubahan. Deteksi perubahan waktu berikutnya berjalan di mana saja, itu akan berjalan juga untuk komponen-komponen yang ditandai.cd.markForCheck()
. Seringkali, perubahan memengaruhi banyak komponen dan di suatu tempat deteksi pendeteksian akan dipanggil. Anda pada dasarnya mengatakan: mari kita pastikan komponen ini juga diperbarui ketika itu terjadi. (Tampilan segera diperbarui di setiap proyek yang saya tulis, tetapi tidak di setiap unit test).cd.detectChanges()
tidak menjalankan deteksi perubahan, gunakan . akan kesalahan dalam hal itu. Ini mungkin berarti Anda mencoba mengedit keadaan komponen leluhur, yang bekerja melawan asumsi bahwa deteksi perubahan Angular dirancang.cd.markForCheck()
detectChanges()
detectChanges()
.markForCheck()
mungkin tidak benar-benar memperbarui tampilan Anda tepat waktu. Unit menguji sesuatu yang memengaruhi tampilan Anda, misalnya, mungkin mengharuskan Anda menelepon secara manualfixture.detectChanges()
saat itu tidak diperlukan dalam aplikasi itu sendiri.detectChanges()
karena Anda tidak perlu menjalankan deteksi perubahan pada leluhur komponen.sumber