AngularJS - 为什么需要 $apply 来正确解决 $q 承诺? [英] AngularJS - why is $apply required to properly resolve a $q promise?
问题描述
我正在尝试在我的 angular 应用程序中编写一个小服务,这将使我能够选择全局 Javascript 对象中指定的配置参数.除非文档准备好,否则我不想尝试访问全局配置对象(因为我无法保证脚本元素在 HTML 中的插入顺序).
I'm trying to write a small service in my angular app which will enable me to pick config parameters specified in global Javascript objects. I don't want to attempt accessing the global config object unless the document is ready (because I cannot guarantee the order in which script elements will be inserted in the HTML).
但是,我不明白为什么我需要调用 $apply
才能将解析实际传播到 then
回调.
However, I can't understand why I need the call to $apply
for the resolution to actually propagate to the then
callback.
myModule.service('GlobalConfigService', ['$q', '$rootScope', function($q, $rootScope) {
var def = $q.defer();
$(document).ready(function() {
def.resolve(MyConfig.val);
$rootScope.$apply();
});
def.promise.then(function () {
console.log('I am called only when $apply() is called. Why?');
});
return def.promise;
}]);
推荐答案
在 AngularJS 中,resolve() 的结果在 $digest 循环内异步传播,而不是立即传播.这意味着使用 then() 注册的回调只会在摘要循环发生时(稍后)被调用.
In AngularJS the results of resolve() are propagated asynchronously, inside a $digest cycle, not immediately. This means that callbacks registered with then() will only be called (later) when a digest cycle occurs.
在您的代码中,没有什么会导致 Angular 进入摘要循环,因此永远不会调用 then() 回调.调用 $apply() 是导致摘要循环运行的一种方法.另一种方式:用ng-click添加一个什么都不做的按钮,然后点击它,它会导致一个摘要循环,你应该看到结果:
In your code, nothing is causing Angular to enter a digest cycle, so the then() callback is never called. Calling $apply() is one way to cause a digest cycle to run. Another way: add a button with ng-click that does nothing, then click that, it will cause a digest cycle and you should see the results:
<button ng-click="">Force digest by clicking me</button>
另见https://stackoverflow.com/a/14657974/215945
这篇关于AngularJS - 为什么需要 $apply 来正确解决 $q 承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!