Jawaban:
Mulai dari AngularJS 1.3 ada metode baru yang disebut $watchGroupuntuk mengamati serangkaian ekspresi.
$scope.foo = 'foo';
$scope.bar = 'bar';
$scope.$watchGroup(['foo', 'bar'], function(newValues, oldValues, scope) {
// newValues array contains the current values of the watch expressions
// with the indexes matching those of the watchExpression array
// i.e.
// newValues[0] -> $scope.foo
// and
// newValues[1] -> $scope.bar
});
$scope.$watchGroup(['mycustomctrl.foo', 'mycustomctrl.bar'],...
newValuesdan oldValuessebagai undefined, sementara individual menonton sifat bekerja seperti biasa.
Dimulai dengan AngularJS 1.1.4 Anda dapat menggunakan $watchCollection:
$scope.$watchCollection('[item1, item2]', function(newValues, oldValues){
// do stuff here
// newValues and oldValues contain the new and respectively old value
// of the observed collection array
});
Contoh plunker di sini
Dokumentasi di sini
$watchCollectiondimaksudkan untuk menyerahkan objek dan memberikan arloji untuk perubahan pada salah satu properti objek, sedangkan $watchGroupdimaksudkan untuk menyerahkan serangkaian properti individual untuk mengawasi perubahan. Sedikit berbeda untuk mengatasi masalah serupa namun berbeda. Fiuh!
$watch parameter pertama juga bisa menjadi fungsi.
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
Jika dua nilai gabungan Anda sederhana, parameter pertama hanyalah ekspresi sudut secara normal. Misalnya, firstName dan lastName:
$scope.$watch('firstName + lastName', function() {
//stuff
});
fullName = firstName + " " + lastNamemengharuskan lewatnya fungsi sebagai argumen pertama (daripada ekspresi sederhana seperti 'firstName, lastName'). Angular sangat kuat, tetapi ada beberapa area di mana ia bisa sangat ramah pengembang dengan cara yang tidak (tampaknya) mengganggu kinerja atau prinsip-prinsip desain.
$scope.$watch('firstName + lastName', function() {...}). Anda juga bisa hanya melakukan dua jam tangan: function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);. Saya menambahkan kasus sederhana ke jawabannya.
Inilah solusi yang sangat mirip dengan kode semu asli Anda yang benar-benar berfungsi:
$scope.$watch('[item1, item2] | json', function () { });
EDIT: Oke, saya pikir ini lebih baik:
$scope.$watch('[item1, item2]', function () { }, true);
Pada dasarnya kita melewatkan langkah json, yang tampaknya bodoh untuk memulai, tetapi tidak berhasil tanpa itu. Kuncinya adalah parameter ke-3 yang sering dihilangkan yang mengaktifkan kesetaraan objek dan bukan kesetaraan referensi. Kemudian perbandingan antara objek array yang kami buat benar-benar berfungsi dengan baik.
TypeError: Object #<Object> has no method '$watchCollection'ini tetapi solusi ini membantu saya untuk menyelesaikan masalah saya!
$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
Anda dapat menggunakan fungsi dalam $ watchGroup untuk memilih bidang objek dalam ruang lingkup.
$scope.$watchGroup(
[function () { return _this.$scope.ViewModel.Monitor1Scale; },
function () { return _this.$scope.ViewModel.Monitor2Scale; }],
function (newVal, oldVal, scope)
{
if (newVal != oldVal) {
_this.updateMonitorScales();
}
});
_this? Bukankah ruang lingkup dimasukkan ke dalam fungsi tanpa secara eksplisit mendefinisikannya?
Mengapa tidak membungkusnya dengan forEach?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
Ini tentang overhead yang sama dengan menyediakan fungsi untuk nilai gabungan, tanpa benar-benar harus khawatir tentang komposisi nilai .
changed()dipanggil setiap kali ada perubahan di salah satu properti. Itu perilaku yang sama persis seolah-olah fungsi untuk nilai gabungan disediakan.
Solusi yang sedikit lebih aman untuk menggabungkan nilai mungkin menggunakan yang berikut ini sebagai $watchfungsi Anda :
function() { return angular.toJson([item1, item2]) }
atau
$scope.$watch(
function() {
return angular.toJson([item1, item2]);
},
function() {
// Stuff to do after either value changes
});
Parameter $ watch first dapat berupa ekspresi atau fungsi sudut . Lihat dokumentasi pada $ scope. $ Watch . Ini berisi banyak info berguna tentang cara kerja metode $ watch: ketika watchExpression dipanggil, cara angular membandingkan hasil, dll.
bagaimana tentang:
scope.$watch(function() {
return {
a: thing-one,
b: thing-two,
c: red-fish,
d: blue-fish
};
}, listener...);
trueparameter ketiga to to scope.$watch(seperti pada contoh Anda), listener()akan diaktifkan setiap kali, karena hash anonim memiliki referensi yang berbeda setiap saat.
return { a: functionA(), b: functionB(), ... }. Saya kemudian memeriksa objek yang dikembalikan nilai baru dan lama terhadap satu sama lain.
$scope.$watch('age + name', function () {
//called when name or age changed
});
Di sini fungsi akan dipanggil saat usia dan nilai nama diubah.
Sudut diperkenalkan $watchGroupdalam versi 1.3 menggunakan yang kita dapat menonton beberapa variabel, dengan satu $watchGroupblok
$watchGroupmengambil array sebagai parameter pertama di mana kita dapat memasukkan semua variabel kita untuk menonton.
$scope.$watchGroup(['var1','var2'],function(newVals,oldVals){
console.log("new value of var1 = " newVals[0]);
console.log("new value of var2 = " newVals[1]);
console.log("old value of var1 = " oldVals[0]);
console.log("old value of var2 = " oldVals[1]);
});