Câu trả lời:
Bắt đầu từ AngularJS 1.3, có một phương thức mới được gọi là $watchGroup
để quan sát một tập hợp các biểu thức.
$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
và oldValues
như undefined
, trong khi xem từng thuộc tính hoạt động như bình thường.
Bắt đầu với AngularJS 1.1.4, bạn có thể sử dụng $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
});
Ví dụ Plunker ở đây
Tài liệu ở đây
$watchCollection
dự định sẽ trao một đối tượng và cung cấp đồng hồ để thay đổi bất kỳ thuộc tính nào của đối tượng, trong khi $watchGroup
dự định sẽ trao một loạt các thuộc tính riêng lẻ để theo dõi các thay đổi. Hơi khác nhau để giải quyết các vấn đề tương tự nhưng khác nhau. Phù!
$watch
tham số đầu tiên cũng có thể là một hàm.
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
Nếu hai giá trị kết hợp của bạn đơn giản, tham số đầu tiên chỉ là biểu thức góc bình thường. Ví dụ: FirstName và LastName:
$scope.$watch('firstName + lastName', function() {
//stuff
});
fullName = firstName + " " + lastName
yêu cầu chuyển một hàm làm đối số đầu tiên (chứ không phải là một biểu thức đơn giản như 'firstName, lastName'
). Angular là SO mạnh mẽ, nhưng có một số lĩnh vực mà nó có thể thân thiện với nhà phát triển hơn rất nhiều theo những cách mà (dường như) không thỏa hiệp các nguyên tắc thiết kế hoặc hiệu suất.
$scope.$watch('firstName + lastName', function() {...})
. Bạn cũng có thể chỉ cần làm hai chiếc đồng hồ : function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
. Tôi đã thêm trường hợp đơn giản để trả lời.
Đây là một giải pháp rất giống với mã giả ban đầu của bạn thực sự hoạt động:
$scope.$watch('[item1, item2] | json', function () { });
EDIT: Được rồi, tôi nghĩ điều này thậm chí còn tốt hơn:
$scope.$watch('[item1, item2]', function () { }, true);
Về cơ bản, chúng tôi bỏ qua bước json, có vẻ như bắt đầu ngu ngốc, nhưng nó không hoạt động mà không có nó. Khóa của chúng là tham số thứ 3 thường bị bỏ qua, bật tính bằng nhau của đối tượng trái ngược với đẳng thức tham chiếu. Sau đó, các so sánh giữa các đối tượng mảng được tạo của chúng tôi thực sự hoạt động đúng.
TypeError: Object #<Object> has no method '$watchCollection'
này nhưng giải pháp này giúp tôi giải quyết vấn đề của mình!
$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
Bạn có thể sử dụng các hàm trong $ watchgroup để chọn các trường của một đối tượng trong phạm vi.
$scope.$watchGroup(
[function () { return _this.$scope.ViewModel.Monitor1Scale; },
function () { return _this.$scope.ViewModel.Monitor2Scale; }],
function (newVal, oldVal, scope)
{
if (newVal != oldVal) {
_this.updateMonitorScales();
}
});
_this
? Không phạm vi được đưa vào các chức năng mà không xác định rõ ràng nó?
Tại sao không chỉ đơn giản là bọc nó trong một forEach
?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
Đó là về chi phí tương tự như việc cung cấp một hàm cho giá trị kết hợp, mà không thực sự phải lo lắng về thành phần giá trị .
changed()
được gọi bất cứ khi nào một cái gì đó thay đổi trong một trong hai thuộc tính. Đó là hành vi chính xác giống như khi một hàm cho giá trị kết hợp được cung cấp.
Một giải pháp an toàn hơn một chút để kết hợp các giá trị có thể là sử dụng như sau dưới dạng $watch
hàm của bạn :
function() { return angular.toJson([item1, item2]) }
hoặc là
$scope.$watch(
function() {
return angular.toJson([item1, item2]);
},
function() {
// Stuff to do after either value changes
});
$ xem tham số đầu tiên có thể là biểu thức góc hoặc hàm. Xem tài liệu về $ scope. $ Watch . Nó chứa rất nhiều thông tin hữu ích về cách phương thức $ watch hoạt động: khi watchExpression được gọi, cách so sánh kết quả, v.v.
làm thế nào về:
scope.$watch(function() {
return {
a: thing-one,
b: thing-two,
c: red-fish,
d: blue-fish
};
}, listener...);
true
tham số thứ ba tới scope.$watch
(như trong ví dụ của bạn), listener()
sẽ kích hoạt mọi lúc, bởi vì hàm băm ẩn danh có một tham chiếu khác nhau mỗi lần.
return { a: functionA(), b: functionB(), ... }
. Sau đó tôi kiểm tra các đối tượng được trả về của các giá trị mới và cũ đối với nhau.
$scope.$watch('age + name', function () {
//called when name or age changed
});
Ở đây hàm sẽ được gọi khi cả giá trị tuổi và tên được thay đổi.
Angular được giới thiệu $watchGroup
trong phiên bản 1.3 sử dụng chúng ta có thể xem nhiều biến, với một $watchGroup
khối
duy nhất $watchGroup
lấy mảng làm tham số đầu tiên trong đó chúng ta có thể bao gồm tất cả các biến để xem.
$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]);
});