提问人:Greg 提问时间:8/14/2012 最后编辑:Mosh FeuGreg 更新时间:7/7/2022 访问量:195179
观看多个$scope属性
Watch multiple $scope attributes
答:
118赞
Andrew Joslin
8/14/2012
#1
$watch
第一个参数也可以是函数。
$scope.$watch(function watchBothItems() {
return itemsCombinedValue();
}, function whenItemsChange() {
//stuff
});
如果两个组合值很简单,则第一个参数通常只是一个角度表达式。例如,firstName 和 lastName:
$scope.$watch('firstName + lastName', function() {
//stuff
});
评论
8赞
XML
8/25/2012
这似乎是一个默认要求包含在框架中的用例。即使是像这样简单的计算属性也需要将函数作为第一个参数传递(而不是像 这样的简单表达式)。Angular 非常强大,但在某些领域,它可以在不(似乎)损害性能或设计原则的方式对开发人员更加友好。fullName = firstName + " " + lastName
'firstName, lastName'
4赞
Andrew Joslin
8/25/2012
好吧$watch只采用一个角度表达式,该表达式在调用的示波器上进行评估。所以你可以做.您也可以只做两块手表:.我在答案中添加了简单的案例。$scope.$watch('firstName + lastName', function() {...})
function nameChanged() {}; $scope.$watch('firstName', nameChanged); $scope.$watch('lastName', nameChanged);
0赞
mb21
9/6/2012
“firstName + lastName”中的加号是字符串连接。所以 angular 现在只是检查串联的结果是否不同。
16赞
Dave Edelhart
10/8/2012
字符串连接需要一点小心 - 如果您将“paran orman”更改为“para norman”,则不会触发响应;最好在第一项和第二项之间放置一个像“\t|\t”这样的分隔符,或者只是坚持使用确定的 JSON
0赞
Aladdin Mhemed
10/24/2012
虽然 Amberjs 很烂,但它内置了这个功能!听听那些棱角分明的家伙。我想做手表是最合理可行的方式。
5赞
Artem Andreev
8/14/2012
#2
$watch的第一个参数可以是角度表达式或函数。请参阅 $scope.$watch 上的文档。它包含许多关于$watch方法如何工作的有用信息:何时调用 watchExpression、angular 如何比较结果等。
11赞
guyk
10/2/2012
#3
合并值的一个稍微安全的解决方案可能是使用以下函数:$watch
function() { return angular.toJson([item1, item2]) }
或
$scope.$watch(
function() {
return angular.toJson([item1, item2]);
},
function() {
// Stuff to do after either value changes
});
4赞
wacamo
11/13/2012
#4
怎么样:
scope.$watch(function() {
return {
a: thing-one,
b: thing-two,
c: red-fish,
d: blue-fish
};
}, listener...);
评论
2赞
Peter V. Mørch
1/27/2014
如果没有第三个参数 to(如您的示例所示),则每次都会触发,因为匿名哈希每次都有不同的引用。true
scope.$watch
listener()
0赞
RevNoah
3/18/2014
我发现这个解决方案适合我的情况。对我来说,它更像是:.然后,我检查新值和旧值的返回对象。return { a: functionA(), b: functionB(), ... }
72赞
Karen Zilles
1/19/2013
#5
这是一个与实际有效的原始伪代码非常相似的解决方案:
$scope.$watch('[item1, item2] | json', function () { });
编辑:好的,我认为这更好:
$scope.$watch('[item1, item2]', function () { }, true);
基本上我们跳过了 json 步骤,这一开始看起来很愚蠢,但如果没有它,它就无法工作。它们的关键是经常被省略的第三个参数,它打开了对象相等性,而不是引用相等性。然后,我们创建的数组对象之间的比较实际上是正确的。
评论
0赞
Calvin Cheng
5/31/2013
我有一个类似的问题。这对我来说是正确的答案。
0赞
null
8/18/2013
如果数组表达式中的项不是简单类型,则两者都有轻微的性能开销。
0赞
Karen Zilles
8/27/2013
这是真的..它正在对组件对象进行全面的深度比较。这可能是也可能不是你想要的。请参阅当前批准的答案,了解使用现代 angular 的版本,该版本未进行完整的深度比较。
0赞
abottoni
9/10/2013
出于某种原因,当我尝试在数组上使用$watchCollection时,我遇到了此错误,但此解决方案帮助我解决了我的问题!TypeError: Object #<Object> has no method '$watchCollection'
0赞
Serge van den Oever
1/28/2014
很酷,您甚至可以观察对象中的值:$scope.$watch('[chaptercontent.Id, anchorid]', function (newValues, oldValues) { ... }, true);
12赞
user187676
5/12/2013
#6
为什么不简单地把它包裹在一个?forEach
angular.forEach(['a', 'b', 'c'], function (key) {
scope.$watch(key, function (v) {
changed();
});
});
这与为组合值提供函数的开销大致相同,而实际上不必担心值组合。
评论
0赞
John Doe
5/13/2013
在这种情况下,log() 会被执行几次,对吧?我认为在嵌套$watch函数的情况下,它不会。它不应该在同时观看多个属性的解决方案中。
0赞
5/13/2013
否,日志仅对每个监视属性的每次更改执行一次。为什么会多次调用它?
0赞
John Doe
5/13/2013
是的,我的意思是,如果我们想同时观看所有这些视频,那就不好用了。
1赞
5/13/2013
当然为什么不呢?我在我的一个项目中就是这样做的。 每当任一属性发生更改时,都会调用。这与为组合值提供函数的行为完全相同。changed()
1赞
bingles
10/30/2014
它略有不同,因为如果数组中的多个项目同时更改,则$watch将仅触发处理程序一次,而不是每个更改的项目触发一次。
292赞
Răzvan Flavius Panda
6/21/2013
#7
从 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
});
评论
109赞
M.K. Safi
9/23/2013
请注意,第一个参数不是数组。它是一个看起来像数组的字符串。
1赞
AdityaSaxena
8/20/2014
谢谢你。如果它对我有用,我会给你一千个金币——当然是虚拟的:)
5赞
Mattygabe
2/28/2015
需要明确的是(我花了几分钟才意识到)旨在传递一个对象并提供对对象任何属性更改的监视,而旨在传递单个属性的数组以监视其更改。略有不同,以解决相似但不同的问题。唷!$watchCollection
$watchGroup
1赞
mostruash
5/4/2016
不知何故,当您使用此方法时,newValues 和 oldValues 始终相等: plnkr.co/edit/SwwdpQcNf78pQ80hhXMr
0赞
Syed Nasir Abbas
7/3/2017
谢谢。它解决了我的问题。使用$watch是否存在任何性能影响/问题?
602赞
Paolo Moretti
5/6/2014
#8
从 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
});
评论
7赞
Kamil Tomšík
1/12/2015
与 $watchCollection('[a, b]') 有什么区别??
30赞
Paolo Moretti
2/25/2015
不同之处在于,您可以使用适当的数组,而不是看起来像数组的字符串
2赞
morels
10/15/2015
我遇到了类似的问题,但使用 controllerAs 模式。就我而言,修复包括在变量前面附加控制器的名称:$scope.$watchGroup(['mycustomctrl.foo', 'mycustomctrl.bar'],...
1赞
Alejandro García Iglesias
4/4/2017
这似乎在 Angular 1.6 上对我不起作用。如果我在函数上放置控制台日志,我可以看到它只运行一次 和 as ,同时单独观察属性照常工作。newValues
oldValues
undefined
4赞
Akash Shinde
4/17/2015
#9
$scope.$watch('age + name', function () {
//called when name or age changed
});
当年龄和名称值都更改时,这里函数将被调用。
评论
2赞
Akash Shinde
4/17/2015
此外,请确保在这种情况下不要使用 angular 传递到回调中的 newValue 和 oldValue 参数,因为它们将是生成的串联,而不仅仅是已更改的字段
15赞
Yang Zhang
5/21/2015
#10
可以使用 $watchGroup 中的函数来选择作用域中对象的字段。
$scope.$watchGroup(
[function () { return _this.$scope.ViewModel.Monitor1Scale; },
function () { return _this.$scope.ViewModel.Monitor2Scale; }],
function (newVal, oldVal, scope)
{
if (newVal != oldVal) {
_this.updateMonitorScales();
}
});
评论
1赞
sg.cc
5/22/2015
你为什么使用?作用域不是在没有明确定义的情况下被转移到函数中吗?_this
1赞
Yang Zhang
5/22/2015
我使用打字稿,呈现的代码是编译结果。
1赞
Vinit Solanki
4/2/2018
#11
在 1.3 版中引入的 Angular 可以使用它来观察多个变量,单个块将数组作为第一个参数,我们可以在其中包含所有要观察的变量。$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]);
});
评论