我正在研究链接承诺以填充我的范围,然后让范围自动更新dom。
我遇到了这方面的问题..如果我在已经解决的承诺上调用“then”,它会创建一个新的承诺(它将异步调用成功函数,但几乎立即调用)。我认为问题是我们已经在调用成功函数时离开了摘要周期,所以dom永远不会更新。
以下是代码:
<div ng-controller="MyCtrl">
Hello, {{name}}! <br/>
{{name2}}<br/>
<button ng-click="go()">Clickme</button><br/>
{{name3}}
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope, $q) {
var data = $q.defer();
setTimeout(function() {$scope.$apply(data.resolve("Some Data"))}, 2000);
var p = data.promise;
$scope.name = p.then(angular.uppercase);
$scope.name2 = p.then(function(x) { return "Hi "+x;});
$scope.go = function() {
$scope.name3 = p.then(function(x) {
// uncomment this to make it work:
//$scope.$apply();
return "Finally: "+x;
});
};
}
是否有某种方法可以在每次链接承诺时不调用$ apply来完成这项工作?
答案 0 :(得分:15)
致quote @ pkozlowski.opensource:
在AngularJS中,承诺解析的结果在$ digest循环内异步传播。因此,只有在进入$ digest循环时才会调用then()注册的回调。
因此,当点击按钮时,我们处于摘要周期。 then()创建一个新的promise,但then()的结果将不会传播,直到 next 摘要周期,它永远不会(因为没有$ timeout,$ http或DOM)事件触发一个)。如果你添加另一个没有任何操作的ng-click按钮,然后点击它,它将导致一个摘要周期,你会看到结果:
<button ng-click="">Force digest by clicking me</button><br/>
这是fiddle,可以做到这一点。
小提琴也使用$ timeout而不是setTimeout - 然后不需要$ apply()。
希望您需要使用$ apply时很清楚。有时您需要手动调用它。