Dari dokumen:
detectChanges (): void
Periksa detektor perubahan dan anak-anaknya.
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.
someFunctionThatIsRunByAThirdPartyCode(){
yourModel.text = "new text";
}
Karena kode ini berada di luar zona Angular (mungkin), kemungkinan besar Anda perlu memastikan untuk mendeteksi perubahan dan memperbarui tampilan, dengan demikian:
myFunction(){
someFunctionThatIsRunByAThirdPartyCode();
// Let's detect the changes that above function made to the model which Angular is not aware of.
this.cd.detectChanges();
}
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:
myFunction(){
this.zone.run(this.someFunctionThatIsRunByAThirdPartyCode);
}
** Anda bisa membungkus fungsi di dalam setTimeout:
myFunction(){
setTimeout(this.someFunctionThatIsRunByAThirdPartyCode,0);
}
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
, karena setTimeout
ditambal oleh zona dan akan berjalan detectChanges
setelah selesai.
Dari dokumen
markForCheck() : void
Tandai semua leluhur ChangeDetectionStrategy yang akan diperiksa.
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:
var obj = {
name:'Milad'
};
Dan kemudian Anda memperbarui / bermutasi seperti:
obj.name = "a new name";
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:
obj.name = "a new name";
Anda perlu melakukan ini:
this.cd.markForCheck();
Sebaliknya, di bawah ini akan menyebabkan deteksi perubahan berjalan:
obj = {
name:"a new name"
};
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:
- Klik
- Keyup
- Acara berlangganan
- dll.
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-bypass ChangeDetectionStrategy
dengan mematikan beberapa data atau Anda telah memperbarui model di dalam setTimeout ;