【发布时间】:2012-08-10 18:16:01
【问题描述】:
有没有办法使用$watch订阅多个对象上的事件
例如
$scope.$watch('item1, item2', function () { });
【问题讨论】:
标签: javascript angularjs events angularjs-watch
有没有办法使用$watch订阅多个对象上的事件
例如
$scope.$watch('item1, item2', function () { });
【问题讨论】:
标签: javascript angularjs events angularjs-watch
从 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
});
【讨论】:
$scope.$watchGroup(['mycustomctrl.foo', 'mycustomctrl.bar'],...
newValues 和 oldValues 为 undefined,同时单独观察属性正常工作。
【讨论】:
$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...);
【讨论】:
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]);
});
【讨论】: