Angularjs $apply in setTimeout

Angularjs $apply in setTimeout,angularjs,apply,ng-switch,Angularjs,Apply,Ng Switch,我知道,$apply用于连接Javascript上下文和AngularJS上下文 下面是一个简单的例子: 模板: <div>{{someVal}}</div> 在上述情况下,我们需要使用$apply 第一个问题: 如果我将上面的javascript修改为: setTimeout(function() { scope.someVal = 123; }, 1000); scope.$watch('someVal', function(val) { cons

我知道,
$apply
用于连接Javascript上下文和AngularJS上下文

下面是一个简单的例子:

模板:

<div>{{someVal}}</div>
在上述情况下,我们需要使用
$apply

第一个问题:

如果我将上面的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>
无需使用
$apply
!!!!为什么?

我发现ngSwitch指令使用
$watch
来监控
属性值。为什么ngSwitch可以在超时回调中查看范围属性的修改

请告诉我上述两个问题的原因。

使用Angularjs而不是setTimeout,您将不需要$apply。同样,如果您使用jquery http调用,请使用angular http服务避免使用$apply。

您可以使用它作为window.setTimeout的包装,这样您就不需要在回调上使用$apply:

$timeout(函数(){ scope.someVal=123;},1000)

当您运行超出Angular的代码时,您需要一种方法让Angular和该值的观察者知道它已经改变了。这就是为什么,它将允许观看者开火

关于第二个问题,为什么范围在更新时没有使用$apply,您应该间接地使用$apply/$digest。为了给您一个更具体的答案,需要一个Plunker来检查代码中的其他内容

来自文档

$apply()用于从angular框架外部执行angular中的表达式。(例如,来自浏览器DOM事件、setTimeout、XHR或第三方库)。因为我们正在调用angular框架,所以我们需要执行异常处理、执行监视的适当范围生命周期

是一个JavaScript函数,因此无论您使用什么,都必须使用$apply()
来更新模型


如果没有
$apply()
,您的第二个示例将不起作用,我已经对
$watch
$apply
问题进行了澄清。请检查。

对不起,我无法访问您的演示。您说得对!我发现$apply for someVal在其他$apply中被触发。。。我对我遇到的事胡说八道。无论如何,谢谢你!第二个问题解决了!$apply for someVal在其他$apply中触发,如。
<div ng-switch on="sub">
    <div ng-switch-when="a">
//state a
    </div>
    <div ng-switch-when="b">
//state b
    </div>
</div>
scope.sub = 'a';
setTimeout(function() {
    scope.sub = 'b';
}, 1000);