我有一个列表,我希望每当它发生变化时都会收到通知。一个简单的$watch
表达式不起作用,我猜测是因为angular正在检查引用相等,而不是结构相等。
<html ng-app>
<head>
</head>
<body ng-controller="Root">
<h1>Base Angular Fiddle</h1>
Times changed: {{timesChanged}}
<ul>
<li ng-repeat="name in names">{{name}}</li>
<li><button ng-click="names.push('another name')">Add</button></li>
</ul>
</body>
</html>
function Root($scope) {
$scope.timesChanged = 0;
$scope.names = ['foo', 'bar', 'baz'];
$scope.$watch('names', function() {
$scope.timesChanged++;
});
}
我希望会发生的是每次调用'names'
时都会调用names.push()
的回调。是否有针对此推荐的解决方法?或者我只是没有正确使用$watch
?
答案 0 :(得分:9)
出于性能原因,您是对的,默认情况下进行角度检查以供参考。参考vs等式的使用取决于$ watch函数的第三个参数的值,正如您可以看到in the docs。只需将其设置为true(默认情况下为false)并且您的小提琴将起作用 - here it is, working.
改变:
$scope.$watch('names', function() {
$scope.timesChanged++;
}, true);
编辑 - 性能影响:
根据变量的大小和复杂程度,比较两个数组/对象显然效率非常低(因此默认情况下通过引用角进行检查)。还有一种方法 - 观察阵列的长度。这有明显的局限性 - 改变一个元素不再触发$ watch函数 - 但可以非常快。这是一个updated fiddle!
答案 1 :(得分:1)
快速添加:
如果您想观看更多特殊的内容,可以这样做:
$scope.$watch(function() {
// Define what you are watching for
// For example convert your array into a string
return String($scope.names);
}, function(newValue, oldValue) {
// Do something cool.
});
这绝对没有names.length
那么快,但你可以玩,找到一个复杂的解决方案。
如果有人感兴趣我使用修改后的Duff设备进行了快速哈希操作:http://jsfiddle.net/flek/mfKT6/1/如果您正在处理大量数据,则此哈希方法也可以更新为错误响应(如只有哈希值第二或第三个字符)