有没有办法使用 $watch
订阅多个对象上的事件
例如
$scope.$watch('item1, item2', function () { });
从 AngularJS 1.3 开始,有一个名为 $watchGroup
的新方法用于观察一组表达式。
$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
});
从 AngularJS 1.1.4 开始,您可以使用 $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
});
Plunker 示例 here
文档here
$watchCollection
旨在传递一个对象并提供对任何对象属性更改的监视,而 $watchGroup
旨在传递一个单独的属性数组以注意更改。解决相似但不同的问题略有不同。呸!
$watch
第一个参数也可以是函数。
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
如果您的两个组合值很简单,则第一个参数通常只是一个角度表达式。例如,名字和姓氏:
$scope.$watch('firstName + lastName', function() {
//stuff
});
fullName = firstName + " " + lastName
这样简单的计算属性也需要传递一个函数作为第一个参数(而不是像 'firstName, lastName'
这样的简单表达式)。 Angular 是如此强大,但在某些领域,它可以以不(似乎)损害性能或设计原则的方式对开发人员更加友好。
$scope.$watch('firstName + lastName', function() {...})
。您也可以只做两个手表:function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
。我在答案中添加了简单的案例。
这是一个与实际有效的原始伪代码非常相似的解决方案:
$scope.$watch('[item1, item2] | json', function () { });
编辑:好的,我认为这更好:
$scope.$watch('[item1, item2]', function () { }, true);
基本上我们跳过了 json 步骤,一开始这似乎很愚蠢,但没有它就无法工作。它们的关键是经常省略的第三个参数,它打开对象相等而不是引用相等。然后我们创建的数组对象之间的比较实际上是正确的。
TypeError: Object #<Object> has no method '$watchCollection'
但这个解决方案可以帮助我解决我的问题!
$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
您可以使用 $watchGroup 中的函数来选择范围内对象的字段。
$scope.$watchGroup(
[function () { return _this.$scope.ViewModel.Monitor1Scale; },
function () { return _this.$scope.ViewModel.Monitor2Scale; }],
function (newVal, oldVal, scope)
{
if (newVal != oldVal) {
_this.updateMonitorScales();
}
});
_this
?在没有明确定义的情况下,范围不会被带到功能中吗?
为什么不简单地将其包装在 forEach
中?
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
它与为组合值提供函数的开销大致相同,而实际上不必担心值的组合。
changed()
。这与提供组合值的函数完全相同的行为。
组合值的稍微安全一点的解决方案可能是使用以下函数作为 $watch
函数:
function() { return angular.toJson([item1, item2]) }
或者
$scope.$watch(
function() {
return angular.toJson([item1, item2]);
},
function() {
// Stuff to do after either value changes
});
$watch 第一个参数可以是 angular expression 或函数。请参阅 $scope.$watch 上的文档。它包含许多有关 $watch 方法如何工作的有用信息:何时调用 watchExpression,角度如何比较结果等。
怎么样:
scope.$watch(function() {
return {
a: thing-one,
b: thing-two,
c: red-fish,
d: blue-fish
};
}, listener...);
scope.$watch
的第三个 true
参数(如您的示例中所示),listener()
每次都会触发,因为匿名哈希每次都有不同的引用。
return { a: functionA(), b: functionB(), ... }
。然后,我将新值和旧值的返回对象相互检查。
$scope.$watch('age + name', function () {
//called when name or age changed
});
当年龄和名称值都更改时,将调用此处的函数。
Angular 在 1.3 版中引入了 $watchGroup
,我们可以使用它来观察多个变量,单个 $watchGroup
块 $watchGroup
将数组作为第一个参数,我们可以在其中包含所有要观察的变量。
$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]);
});
$scope.$watchGroup(['mycustomctrl.foo', 'mycustomctrl.bar'],...
newValues
和oldValues
作为undefined
,同时单独观察属性正常工作。