Jawaban:
Mulai dari AngularJS 1.3 ada metode baru yang disebut $watchGroup
untuk 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'],...
newValues
dan oldValues
sebagai 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
$watchCollection
dimaksudkan untuk menyerahkan objek dan memberikan arloji untuk perubahan pada salah satu properti objek, sedangkan $watchGroup
dimaksudkan 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 + " " + lastName
mengharuskan 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 $watch
fungsi 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...);
true
parameter 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 $watchGroup
dalam versi 1.3 menggunakan yang kita dapat menonton beberapa variabel, dengan satu $watchGroup
blok
$watchGroup
mengambil 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]);
});