Anda harus sadar tentang cara kerja AngularJS untuk memahaminya.
Siklus pencernaan dan $ lingkup
Pertama dan terpenting, AngularJS mendefinisikan konsep siklus digest . Siklus ini dapat dianggap sebagai loop, di mana AngularJS memeriksa apakah ada perubahan pada semua variabel yang ditonton oleh semua $scope
s. Jadi, jika Anda telah $scope.myVar
menetapkan di controller Anda dan variabel ini ditandai untuk diawasi , maka Anda secara implisit memberitahu AngularJS untuk memantau perubahan pada myVar
setiap iterasi dari loop.
Pertanyaan tindak lanjut yang wajar adalah: Apakah segala sesuatu terkait dengan $scope
diawasi? Untungnya tidak. Jika Anda akan melihat perubahan pada setiap objek di Anda $scope
, maka dengan cepat loop intis akan membutuhkan waktu lama untuk mengevaluasi dan Anda akan dengan cepat mengalami masalah kinerja. Itulah sebabnya tim AngularJS memberi kami dua cara untuk menyatakan beberapa $scope
variabel sedang diawasi (baca di bawah).
$ watch membantu mendengarkan perubahan $ scope
Ada dua cara untuk mendeklarasikan $scope
variabel sebagai yang diawasi.
- Dengan menggunakannya di templat Anda melalui ekspresi
<span>{{myVar}}</span>
- Dengan menambahkannya secara manual melalui
$watch
layanan
Iklan 1) Ini adalah skenario yang paling umum dan saya yakin Anda pernah melihatnya sebelumnya, tetapi Anda tidak tahu bahwa ini telah membuat arloji di latar belakang. Ya, benar! Menggunakan arahan AngularJS (seperti ng-repeat
) juga dapat membuat jam tangan implisit.
Iklan 2) Ini adalah bagaimana Anda membuat jam tangan Anda sendiri . $watch
layanan membantu Anda untuk menjalankan beberapa kode ketika beberapa nilai yang melekat pada $scope
telah berubah. Ini jarang digunakan, tetapi kadang-kadang bermanfaat. Misalnya, jika Anda ingin menjalankan beberapa kode setiap kali 'myVar' berubah, Anda dapat melakukan hal berikut:
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // This will trigger $watch expression to kick in
};
}
$ apply memungkinkan untuk mengintegrasikan perubahan dengan siklus digest
Anda dapat menganggap $apply
fungsinya sebagai mekanisme integrasi . Anda lihat, setiap kali Anda mengubah beberapa variabel yang ditonton yang melekat pada$scope
objek secara langsung, AngularJS akan tahu bahwa perubahan telah terjadi. Ini karena AngularJS sudah tahu untuk memantau perubahan itu. Jadi jika itu terjadi dalam kode yang dikelola oleh kerangka kerja, siklus intisari akan melanjutkan.
Namun, terkadang Anda ingin mengubah beberapa nilai di luar dunia AngularJS dan melihat perubahannya menyebar secara normal. Pertimbangkan ini - Anda memiliki $scope.myVar
nilai yang akan dimodifikasi dalam $.ajax()
penangan jQuery . Ini akan terjadi di beberapa titik di masa depan. AngularJS tidak sabar menunggu hal ini terjadi, karena belum diinstruksikan untuk menunggu di jQuery.
Untuk mengatasinya, $apply
sudah diperkenalkan. Ini memungkinkan Anda memulai siklus pencernaan secara eksplisit. Namun, Anda hanya boleh menggunakan ini untuk memigrasi beberapa data ke AngularJS (integrasi dengan kerangka kerja lain), tetapi jangan pernah menggunakan metode ini dikombinasikan dengan kode AngularJS biasa, karena AngularJS akan membuang kesalahan saat itu.
Bagaimana semua ini terkait dengan DOM?
Nah, Anda harus benar-benar mengikuti tutorial lagi, sekarang setelah Anda tahu semua ini. Siklus intisari akan memastikan bahwa UI dan kode JavaScript tetap disinkronkan, dengan mengevaluasi setiap pengamat yang terpasang pada semua $scope
selama tidak ada perubahan. Jika tidak ada lagi perubahan yang terjadi di loop digest, maka itu dianggap selesai.
Anda bisa melampirkan objek ke $scope
objek baik secara eksplisit di Controller, atau dengan mendeklarasikannya dalam {{expression}}
bentuk langsung di tampilan.
Saya harap ini membantu menjelaskan beberapa pengetahuan dasar tentang semua ini.
Bacaan lebih lanjut:
Di AngularJS, kami memperbarui model kami, dan tampilan / templat kami memperbarui DOM "secara otomatis" (melalui petunjuk bawaan atau kustom).
$ apply dan $ watch, keduanya merupakan metode Lingkup, tidak terkait dengan DOM.
The Konsep halaman (bagian "Runtime") memiliki penjelasan yang cukup bagus dari $ mencerna lingkaran, $ berlaku, antrian $ evalAsync dan daftar $ menonton. Inilah gambar yang menyertai teks:
Kode apa pun yang memiliki akses ke lingkup - biasanya pengontrol dan arahan (fungsi tautan dan / atau pengontrol mereka) - dapat mengatur " watchExpression " yang akan dievaluasi AngularJS terhadap cakupan itu. Evaluasi ini terjadi setiap kali AngularJS memasuki loop $ digest (khususnya, loop "$ watch list"). Anda dapat menonton properti lingkup individual, Anda dapat menentukan fungsi untuk menonton dua properti secara bersamaan, Anda dapat menonton panjang array, dll.
Ketika hal-hal terjadi "di dalam AngularJS" - misalnya, Anda mengetik ke dalam kotak teks yang mengaktifkan penyatuan data dua arah AngularJS (yaitu, menggunakan model-ng), panggilan panggil balik $ http, dll. - $ apply telah dipanggil, jadi kami Di dalam kotak "AngularJS" pada gambar di atas. Semua watchExpressions akan dievaluasi (mungkin lebih dari sekali - sampai tidak ada perubahan lebih lanjut terdeteksi).
Ketika hal-hal terjadi "di luar AngularJS" - misalnya, Anda menggunakan bind () dalam sebuah arahan dan kemudian peristiwa itu terjadi, mengakibatkan panggilan balik Anda dipanggil, atau beberapa panggilan panggil balik terdaftar jQuery terdaftar - kami masih berada dalam kotak "Asli". Jika kode panggilan balik memodifikasi apa pun yang ditonton $ watch apa pun, panggil $ berlaku untuk masuk ke persegi panjang AngularJS, menyebabkan $ digest loop dijalankan, dan karenanya AngularJS akan melihat perubahan dan melakukan keajaibannya.
sumber
scope.$apply(scope.model)
, saya tidak mengerti data apa yang ditransfer dan bagaimana cara ditransfer ke tempat yang tepat dalam model?scope.$apply(scope.model)
hanya akan mengevaluasiscope.model
sebagai ekspresi Angular, dan kemudian memasukkan loop $ digest. Dalam artikel yang Anda referensikan, mungkinscope.$apply()
akan cukup, karena modelnya sudah $ diawasi. Fungsi stop () memperbarui model (saya percaya toUpdate adalah referensi ke scope.model), dan kemudian $ apply dipanggil.$watch
di laman, dan tautan kedua rusak - seperti sekarang, bagaimanapun). Sungguh menyakitkan, versi arsip tidak menembolok proses async apa pun yang menciptakan konten.AngularJS memperluas loop peristiwa ini , menciptakan sesuatu yang disebut
AngularJS context
.$ tonton ()
Setiap kali Anda mengikat sesuatu di UI Anda memasukkan
$watch
dalam$watch
daftar .Di sini kita memiliki
$scope.user
, yang terikat pada input pertama, dan kita miliki$scope.pass
, yang terikat pada input kedua. Melakukan ini, kami menambahkan dua$watch
es ke$watch
daftar .Ketika templat kita dimuat, AKA dalam fase penautan, kompiler akan mencari setiap arahan dan membuat semua
$watch
es yang diperlukan.AngularJS menyediakan
$watch
,$watchcollection
dan$watch(true)
. Di bawah ini adalah diagram rapi yang menjelaskan ketiganya diambil dari pengamat secara mendalam .http://jsfiddle.net/2Lyn0Lkb/
$digest
lingkaranKetika browser menerima suatu peristiwa yang dapat dikelola oleh konteks AngularJS,
$digest
loop akan diaktifkan. Loop ini dibuat dari dua loop yang lebih kecil. Satu memproses$evalAsync
antrian, dan yang lainnya memproses$watch list
. Surat$digest
wasiat akan melalui daftar$watch
yang kita milikiDi sini kita hanya punya satu
$watch
karena ng-klik tidak membuat jam tangan.Kami menekan tombol.
$digest
Loop akan berjalan dan akan meminta setiap $ menonton untuk perubahan.$watch
yang mengawasi perubahan $ scope.name melaporkan perubahan, itu akan memaksa$digest
loop lain .$digest
loop. Itu berarti bahwa setiap kali kita menulis surat di input, loop akan berjalan memeriksa setiap$watch
halaman ini.$ terapkan ()
Jika Anda menelepon
$apply
ketika suatu peristiwa dipecat, itu akan melalui konteks sudut, tetapi jika Anda tidak menyebutnya, itu akan berjalan di luar itu. Semudah itu.$apply
akan memanggil$digest()
loop secara internal dan akan mengulangi semua jam tangan untuk memastikan DOM diperbarui dengan nilai yang baru diperbarui.The
$apply()
metode akan memicu pengamat pada seluruh$scope
rantai sedangkan$digest()
metode hanya akan memicu pengamat pada saat$scope
dan nyachildren
. Ketika tidak ada objek yang lebih tinggi yang$scope
perlu tahu tentang perubahan lokal, Anda bisa menggunakannya$digest()
.sumber
Saya menemukan sangat mendalam video yang meliputi
$watch
,$apply
,$digest
dan mencerna siklus di:AngularJS - Memahami Watcher, $ watch, $ watchGroup, $ watchCollection, ng-change
AngularJS - Memahami siklus digest (fase digest atau proses digest atau digest loop)
AngularJS Tutorial - Memahami $ apply dan $ digest (mendalam)
Berikut adalah beberapa slide yang digunakan dalam video tersebut untuk menjelaskan konsep-konsep (untuk berjaga-jaga, jika tautan di atas dihapus / tidak berfungsi).
Pada gambar di atas, "$ scope.c" tidak ditonton karena tidak digunakan dalam binding data apa pun (dalam markup). Dua lainnya (
$scope.a
dan$scope.b
) akan diawasi.Dari gambar di atas: Berdasarkan pada acara browser masing-masing, AngularJS menangkap acara, melakukan siklus digest (menelusuri semua jam tangan untuk perubahan), menjalankan fungsi jam tangan dan memperbarui DOM. Jika bukan acara browser, siklus intisari dapat dipicu secara manual menggunakan
$apply
atau$digest
.Lebih lanjut tentang
$apply
dan$digest
:sumber
Ada
$watchGroup
dan$watchCollection
juga. Secara khusus,$watchGroup
sangat membantu jika Anda ingin memanggil fungsi untuk memperbarui objek yang memiliki beberapa properti dalam tampilan yang bukan objek dom, misalnya untuk tampilan lain di kanvas, WebGL atau permintaan server.Di sini, tautan dokumentasi .
sumber
$watchCollection
tetapi saya melihat Anda sudah melakukannya. Ini dokumentasi tentang hal itu dari situs AngularJS. Mereka memberikan visual yang sangat bagus dari$watch
kedalaman. Perhatikan informasinya dekat dengan bagian bawah halaman.Selesai membaca SEMUA hal di atas, membosankan dan mengantuk (maaf tapi itu benar). Sangat teknis, mendalam, terperinci, dan kering. Kenapa saya menulis? Karena AngularJS sangat besar, banyak konsep yang saling terhubung dapat mengubah siapa pun menjadi gila. Saya sering bertanya pada diri sendiri, apakah saya tidak cukup pintar untuk memahaminya? Tidak! Itu karena sangat sedikit yang bisa menjelaskan teknologi dalam bahasa for-dummie tanpa semua terminologi! Oke, izinkan saya mencoba:
1) Mereka semua adalah event-driven. (Saya mendengar tawa, tetapi baca terus)
Jika Anda tidak tahu apa itu event-driven. Lalu anggap Anda meletakkan tombol di halaman tersebut, kaitkan dengan fungsi menggunakan "klik", menunggu pengguna mengkliknya untuk memicu tindakan yang Anda tanam di dalam fungsi. Atau pikirkan "pemicu" dari SQL Server / Oracle.
2) $ jam adalah "on-klik".
Yang spesial tentang ini adalah dibutuhkan 2 fungsi sebagai parameter, yang pertama memberikan nilai dari acara tersebut, yang kedua mempertimbangkan nilai ...
3) $ digest adalah bos yang memeriksa sekitar tanpa lelah , bla-bla-bla tapi bos yang baik.
4) $ apply memberi Anda cara ketika Anda ingin melakukannya secara manual , seperti bukti-gagal (kalau-kalau klik tidak masuk, Anda memaksanya untuk berjalan.)
Di rumah makan,
- WAITER
seharusnya menerima pesanan dari pelanggan, ini
- MANAGER berlarian untuk memastikan semua pelayan terjaga, responsif terhadap tanda-tanda perubahan dari pelanggan. Ini adalah
$digest()
- PEMILIK memiliki kekuatan tertinggi untuk mengarahkan semua orang atas permintaan, ini
$apply()
sumber