$ apply在setTimeout中

时间:2014-01-31 04:19:27

标签: angularjs apply ng-switch

我认为$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个问题的原因。

3 个答案:

答案 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。