0

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

一个简单的例子如下:

模板:

<div>{{someVal}}</div>

控制器中的javascript:

setTimeout(function() {
    scope.$apply(function(){scope.someVal = 123});
}, 1000);

我们需要$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>

当我修改subin 控制器时:

scope.sub = 'a';
setTimeout(function() {
    scope.sub = 'b';
}, 1000);

没必要用$apply!!!!为什么?

我发现 ngSwitch 指令用于$watch监视on属性值。为什么ngSwitch可以看到超时回调中修改的范围属性??????

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

4

3 回答 3

1

来自AngularJs文档

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

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

如果没有,您的第二个示例将无法工作$apply(),我已经做了一个demo来澄清$watchand$apply问题。请检查一下。

于 2014-01-31T05:26:01.663 回答
1

您可以使用$timeout,它是 window.setTimeout 的包装器,这样您就不需要在回调中使用 $apply 了:

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

当您在 Angular 之外运行代码时,您需要一种方法让 Angular 和该值的观察者知道它已更改。这就是$apply的用途,它将允许 watch listeners 触发

关于你的第二个问题,为什么范围在没有 $apply 的情况下更新,你应该以某种方式间接触发 $apply/$digest。为了给你一个更具体的答案,一个 Plunker 将是必要的,以检查你的代码中还有什么。

于 2014-01-31T04:30:49.917 回答
0

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

于 2014-01-31T04:26:35.827 回答