Saya tahu bahwa keduanya Watchers
dan Observers
dihitung segera setelah sesuatu dalam $scope
perubahan di AngularJS. Tapi tidak bisa mengerti apa sebenarnya perbedaan antara keduanya.
Pemahaman awal saya adalah yang Observers
dihitung untuk ekspresi sudut yang merupakan kondisi di sisi HTML tempat Watchers
dieksekusi ketika $scope.$watch()
fungsi dieksekusi. Apakah saya berpikir dengan benar?
javascript
angularjs
Abilash
sumber
sumber
Jawaban:
$ observ () adalah metode padaobjek Attributes , dan karenanya, hanya dapat digunakan untuk mengamati / menonton perubahan nilai atribut DOM. Ini hanya digunakan / disebut arahan dalam. Gunakan $ mengamati ketika Anda perlu mengamati / menonton atribut DOM yang berisi interpolasi (yaitu, {{}} 's).
Misalnya,
attr1="Name: {{name}}"
maka dalam Instruksi:attrs.$observe('attr1', ...)
.(Jika Anda mencobanya
scope.$watch(attrs.attr1, ...)
tidak akan berhasil karena {{}} s - Anda akan mendapatkannyaundefined
.) Gunakan $ watch untuk yang lainnya.$ watch () lebih rumit. Ia dapat mengamati / menonton "ekspresi", di mana ekspresi dapat berupa fungsi atau string. Jika ekspresi adalah string, itu adalah $ parse 'd (yaitu, dievaluasi sebagai ekspresi Angular ) ke dalam suatu fungsi. (Fungsi inilah yang disebut setiap siklus intisari.) Ekspresi string tidak dapat berisi {{}}. $ watch adalah metode padaobjek Lingkup , sehingga dapat digunakan / dipanggil di mana pun Anda memiliki akses ke objek lingkup, maka dalam
Karena string dievaluasi sebagai ekspresi Angular, $ watch sering digunakan ketika Anda ingin mengamati / menonton properti model / lingkup. Misalnya,,
attr1="myModel.some_prop"
lalu dalam fungsi pengontrol atau tautan:scope.$watch('myModel.some_prop', ...)
atauscope.$watch(attrs.attr1, ...)
(atauscope.$watch(attrs['attr1'], ...)
).(Jika Anda mencoba,
attrs.$observe('attr1')
Anda akan mendapatkan stringmyModel.some_prop
, yang mungkin bukan yang Anda inginkan.)Seperti dibahas dalam komentar pada jawaban @ PrimosK, semua $ mengamati dan $ jam diperiksa setiap siklus intisari .
Arahan dengan lingkup isolasi lebih rumit. Jika sintaks '@' digunakan, Anda dapat $ mengamati atau $ menonton atribut DOM yang berisi interpolasi (yaitu, {{}}). (Alasan kerjanya dengan $ watch adalah karena sintaks '@' melakukan interpolasi untuk kita, maka $ watch melihat string tanpa {{}} 's.) Untuk membuatnya lebih mudah untuk mengingat yang harus digunakan saat, saya sarankan menggunakan $ perhatikan untuk kasus ini juga.
Untuk membantu menguji semua ini, saya menulis sebuah Plunker yang mendefinisikan dua arahan. Satu (
d1
) tidak membuat ruang lingkup baru, yang lain (d2
) menciptakan ruang lingkup terisolasi. Setiap arahan memiliki enam atribut yang sama. Setiap atribut adalah $ observ'd dan $ watch'ed.Lihatlah log konsol untuk melihat perbedaan antara $ observ dan $ watch dalam fungsi penautan. Kemudian klik tautan dan lihat $ mengamati dan $ jam tangan mana yang dipicu oleh perubahan properti yang dilakukan oleh pengendali klik.
Perhatikan bahwa ketika fungsi tautan berjalan, atribut apa pun yang mengandung {{}} belum dievaluasi (jadi jika Anda mencoba memeriksa atribut, Anda akan mendapatkannya
undefined
). Satu-satunya cara untuk melihat nilai-nilai yang diinterpolasi adalah dengan menggunakan $ observ (atau $ watch jika menggunakan lingkup isolat dengan '@'). Oleh karena itu, mendapatkan nilai atribut ini adalah operasi yang tidak sinkron . (Dan inilah mengapa kita membutuhkan fungsi $ mengamati dan $ menonton.)Terkadang Anda tidak perlu $ mengamati atau $ menonton. Misalnya, jika atribut Anda berisi nomor atau boolean (bukan string), hanya mengevaluasi sekali:
attr1="22"
, maka dalam, katakanlah, fungsi menghubungkan Anda:var count = scope.$eval(attrs.attr1)
. Jika itu hanya string konstan -attr1="my string"
- maka gunakan sajaattrs.attr1
direktif Anda (tidak perlu $ eval ()).Lihat juga posting grup google Vojta tentang $ watch expressions.
sumber
ng-src/ng-href
penggunaanattr.$observe
bukanscope.$watch
itu?@
sintaks. Saya percaya tidak ada perbedaan kinerja (tapi saya belum melihat kode sumber yang sebenarnya).Jika saya mengerti pertanyaan Anda dengan benar, Anda bertanya apa bedanya jika Anda mendaftar dengan panggilan balik pendengar
$watch
atau jika Anda melakukannya$observe
.Register callback dengan
$watch
dipecat ketika$digest
dieksekusi.Callback terdaftar dengan
$observe
dipanggil ketika nilai perubahan atribut yang mengandung interpolasi (misalnyaattr="{{notJetInterpolated}}"
).Di dalam arahan Anda dapat menggunakan keduanya dengan cara yang sangat mirip:
atau
sumber
$digest
fase, aman untuk mengasumsikan bahwa$observe
panggilan balik akan dipanggil$digest
. Dan$watch
panggilan balik juga akan dipanggil$digest
tetapi kapan pun nilainya berubah. Saya pikir mereka melakukan pekerjaan yang sama persis: "perhatikan ekspresi, panggil panggilan balik nilainya berubah". Perbedaan kata kunci mungkin hanya gula sintaksis karena tidak membingungkan pengembang.Saya pikir ini cukup jelas:
Perlu diingat : kedua fungsi memiliki dua argumen,
function (oldValue, newValue)
Saya telah membuat plunker, jadi Anda benar-benar bisa memahami pemanfaatan keduanya. Saya telah menggunakan analogi Chameleon untuk membuatnya lebih mudah digambarkan.
sumber
Mengapa $ mengamati berbeda dari $ menonton?
WatchExpression dievaluasi dan dibandingkan dengan nilai sebelumnya setiap siklus digest (), jika ada perubahan dalam nilai watchExpression, fungsi jam disebut.
$ observ khusus untuk mengamati nilai yang diinterpolasi. Jika nilai atribut direktif diinterpolasi, misalnya
dir-attr="{{ scopeVar }}"
, fungsi mengamati hanya akan dipanggil ketika nilai interpolasi diatur (dan karena itu ketika $ digest telah menentukan pembaruan harus dilakukan). Pada dasarnya sudah ada pengamat interpolasi, dan fungsi $ mengamati dukung itu.Lihat $ mengamati & $ set di compile.js
sumber