希望有AngularJS的作者来做,但是我相信$ digest()必须在$ rootScope上调用,因为转发器中触发的更改可能会在其他范围(甚至$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中还包含一个对象,以说明观察者评估确实需要从最顶层开始。
解决方法在AngularJS范围内。在每个事件处理程序(输入指令的keydown / input事件,select指令的change事件等)上调用$apply()。
看小例子。似乎ngRepeat在每次击键时都会重新计算并重绘,尽管事实是另一个作用域发生了更改。
知道这种决定的理由将是很有趣的。