在AngularJS范围内,每个事件处理程序调用$apply()(keydown /输入指令的输入事件,select指令的更改事件等)和其他一些情况.
见small example.似乎在每个键盘上都重新计算和重绘了ngRepeat,尽管其他范围内发生了变化.
了解这样的决定的理由将是有趣的.
对于AngularJS作者来说,这是非常好的,但我相信$digestScope()需要在$rootScope上调用,因为在中继器中触发的变化可能会在其他范围(甚至$rootScope)中产生副作用.
事实是,在子范围中触发的方法可能会影响父范围中的对象(因为子范围从父级范围继承).因此,即使在子范围中定义的函数不能从父范围修改对象引用,它们仍然可以修改父作用域中定义的对象中的值.
以上可能听起来有点隐蔽,所以让我们考虑一个(有点人为的)例子,其中列出了一些项目:
$scope.items = [{name: 'foo',value:0},{name: 'bar',{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中的一个对象来说明观察者的评估真的需要从最上面开始.