我认为$apply
用于连接Javascript上下文和AngularJS上下文。
一个简单的例子如下:
模板:
<div>{{someVal}}</div>
控制器中的javascript:
setTimeout(function() {
scope.$apply(function(){scope.someVal = 123});
}, 1000);
我们需要在上述情况下使用$apply
。
First Qustion:
如果我将上面的javascript修改为:
setTimeout(function() {
scope.someVal = 123;
}, 1000);
scope.$watch('someVal', function(val) {
console.info(someVal);
});
没有关于someVal的控制台修改为123 ...为什么?我们不能看超时回调中修改的表达式吗?
第二个问题:
如果我们使用如下的ngSwitch指令:
<div ng-switch on="sub">
<div ng-switch-when="a">
//state a
</div>
<div ng-switch-when="b">
//state b
</div>
</div>
当我修改控制器中的sub
时:
scope.sub = 'a';
setTimeout(function() {
scope.sub = 'b';
}, 1000);
无需使用$apply
!!!!为什么呢?
我发现ngSwitch指令使用$watch
来监控on
属性值。为什么ngSwitch可以在超时回调中监视修改范围属性?????
请告诉我上述2个问题的原因。
答案 0 :(得分:1)
你可以使用$timeout作为window.setTimeout的包装器,这样你就不需要在回调中使用$ apply:
$ timeout(function(){ scope.someVal = 123; },1000);
当你运行Angular之外的代码时,你需要一种让Angular和该值的观察者知道它已经改变的方法。这就是$apply的用途,它将允许手表听众解雇
关于你的第二个问题,为什么范围是在没有$ apply的情况下更新,你应该以某种方式间接解雇$ apply / $ digest。为了给你一个更具体的答案,需要一个Plunker来检查你的代码还有什么。
答案 1 :(得分:1)
来自AngularJs文档
$ apply()用于从角度框架外部以角度执行表达式。 (例如,来自浏览器DOM事件,setTimeout,XHR或第三方库)。因为我们正在调用角度框架,所以我们需要执行异常处理的适当范围生命周期,执行监视。
window.setTimeout是一个JavaScript函数,因此无论您使用什么setTimeout
,都必须使用$ apply()来更新模型。
你的第二个例子在没有$apply()
的情况下无效,我已经做了 demo 来澄清$watch
和$apply
问题。请检查一下。
答案 2 :(得分:0)
使用Angularjs $timeout service代替setTimeout,您不需要$ apply。同样的事情是,如果您使用jquery http调用,请使用angular http服务以避免使用$ apply。