在AngularJS作用域中,$apply()在每个事件处理程序(输入指令的keydown/输入事件、选择指令的更改事件等)和其他一些情况下被调用。
参见small example。似乎ngRepeat在每次击键时都会重新计算和重新绘制,尽管在另一个作用域中发生了更改。
了解这种决定的理由将是一件有趣的事情。
发布于 2012-09-11 05:32:11
如果有AngularJS的作者参与,那就太好了,但我认为需要在$rootScope上调用$digest(),因为在中继器中触发的更改可能会在其他作用域(甚至是$rootScope)中产生副作用。
问题是,在子作用域中触发的方法可以影响父作用域中的对象(因为子作用域继承父作用域)。因此,即使在子作用域中定义的函数不能修改父作用域中的对象引用,它们仍然可以修改父作用域中定义的对象中的值。
上面的可能听起来有点神秘,所以让我们考虑一个带有项目列表的(有点人工的)示例:
$scope.items = [{name: 'foo', value:0}, {name: 'bar', value:0}, {name: 'baz', value:0}];现在,让我们使用ng-Repeat来显示上面的列表,假设单击一个项目应该递增其他项目的值(同样,这个示例有点做作,但这里的重点是在一个作用域中触发的操作可能在其他作用域中产生副作用)。可能是这样的:
$scope.incOther = function(item) {
for (var i=0; i<$scope.items.length; i++){
if ($scope.items[i] !== item){
$scope.items[i].value++;
}
}
};示例函数将修改其他作用域和AngularJS中的值,为了显示正确的结果,需要计算父作用域中的监视器(直到$rootScope,因为我们不知道对象是在哪里定义的)。
以下是说明这一点的完整jsFiddle:http://jsfiddle.net/pkozlowski_opensource/Z6e5g/3/
事实上,上面的jsFiddle还在$rootScope中包含了一个对象,以说明观察者评估确实需要从最高层开始。
https://stackoverflow.com/questions/12333410
复制相似问题