我正在研究链接诺言以填充我的范围,然后让范围自动更新dom。
但是,我遇到了问题。如果我在已经解决的Promise上调用“ then”,它将创建一个新的Promise(它将异步但几乎立即调用成功函数)。我认为问题在于,在调用成功函数时,我们已经离开了摘要周期,因此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; }); }; }
http://jsfiddle.net/QZM4d/
有什么方法可以使此工作在我每次连锁承诺时都无需调用$ apply?
要引用 @ pkozlowski.opensource:
在AngularJS中,承诺解析的结果在$ digest周期内异步传播。因此,仅在进入$ digest循环后才会调用then()注册的回调。
因此,单击该按钮时,我们处于摘要周期。then()创建了一个新的promise,但是then()的结果要到 下一个 摘要周期才会传播,该摘要周期永远不会到来(因为没有$ timeout或$ http或DOM事件来触发它)。如果您用ng- click添加另一个不执行任何操作的按钮,然后单击该按钮,将导致摘要周期,您将看到结果:
<button ng-click="">Force digest by clicking me</button><br/>
这是一个小提琴。
小提琴还使用$ timeout而不是setTimeout -则不需要$ apply()。
希望您何时需要使用$ apply清楚。有时您确实需要手动调用它。