在我的AngularJS应用程序中,我有2个未嵌套的控制器。调用$ scope。$ apply方法似乎也会影响其他兄弟范围。
在下面的jsfiddle中,似乎每当ControllerTwo每秒更新一次时,就会评估ControllerOne的{{doubleMe(x)}}表达式。这可以从控制台消息中显示。
我可以理解为什么只要文本输入(在同一范围内)发生变化就会对该表达式进行求值,但是为什么$ scope。$适用于另一个范围会导致该表达式也被重新评估?
请注意,我可以通过使用$ timeout来避免$ scope。$ apply,但会观察到结果。
<!-- HTML file -->
<div ng-app>
<h1>Root</h1>
<div ng-controller="ControllerOne">
<h2>Scope One</h2>
1 * 2 = {{doubleMe(1)}}<br/>
2 * 2 = {{doubleMe(2)}}<br/>
3 * 2 = {{doubleMe(3)}}<br/>
<input ng-model="text">
</div>
<div ng-controller="ControllerTwo">
<h2>Scope Two</h2>
{{clock.now | date:'yyyy-MM-dd HH:mm:ss'}}
</div>
</div>
// js file
function ControllerOne($scope) {
var counter=1;
$scope.doubleMe = function(input) {
console.log(counter++);
return input*2;
}
$scope.text = "Change Me";
}
function ControllerTwo($scope) {
$scope.clock = {
now: new Date()
};
var updateClock = function() {
$scope.clock.now = new Date()
};
setInterval(function() {
$scope.$apply(updateClock);
}, 1000);
}
答案 0 :(得分:4)
正如您所见$scope.$apply = $rootScope.$digest //+ some error handling
,因为$scope.$apply
使用$ rootScope,它会影响其所有后代。
所以如果更新子作用域,可以调用$scope.$digest
来仅检查该作用域及其后代,从而减少脏检查的数量并提高性能。
示例强>
我更改了您的代码并添加了$ digest。
setInterval(function() {
$scope.clock.now = new Date();
$scope.$digest();
}, 1000);
答案 1 :(得分:0)
* # Pseudo-Code of `$apply()` * <pre> function $apply(expr) { try { return $eval(expr); } catch (e) { $exceptionHandler(e); } finally { $root.$digest(); } } * </pre>
Alex是正确的,如果您只想让您的更改反映在当前范围及其子项中,则scope.$digest()
是可以使用的。但是,AngularJS经常不鼓励这样做,因为表达式通常会产生副作用,修改全局对象,如服务,这些对象又可以修改兄弟范围。