$ http会在什么时候触发摘要周期?

时间:2015-03-01 17:46:03

标签: javascript angularjs

我的假设是它在.success回调完成执行后发生。与

相反
  • .success回调完成之前。
  • 请求发出后。

考虑以下代码:

notes.service.js

angular.module('notes').service('notes', ['$http', 
function($http) {
    var obj = {};

    this.getNotes = function() {
        $http.get('/notes').success(function(notesResponse) {
            obj.notes = notesResponse;
        });
        return obj;
    };
}]);

notes.controller.js

angular.module('notes').controller('NotesCtrl', ['notes', 
function(notes) {
    /* 
        $scope.$$watchers = [
            'notesCtrl.obj', cb
        ];
    */

    this.obj = notes.getNotes();    
}]);

list.html

<div class='page-header'>
    <h1>List of Notes</h1>
</div>

<ul>
    <li ng-repeat='note in notesCtrl.obj.notes track by note.id'>{{note | json}}</li>
</ul>

想象一下,GET请求在发回响应之前需要一个小时。

  • 该服务将发回{}
  • 在控制器中,this.obj将设置为{}
  • 在视图中,notesCtrl.obj.notesundefined,因此ng-repeat不会发生。
  • 一小时后,当响应回来时......它会更新该对象。服务指向它,控制器指向它并且视图指向它。所以他们都得到“更新”(它确实是更新的对象;指针不会改变,所以它们并没有真正被“更新”)。
  • 响应触发.success的回调,进行更新,一旦.success的回调结束,就会启动摘要周期。
  • 摘要周期看到notesCtrl.obj已更改,因此会运行相应的回调,从而更新DOM。

这是对的吗?

此外,$http会触发$digest还是$apply?如果它触发$digest,它如何知道调用它的$scope?例如,服务中的$http$scope无关(是吗?)。

2 个答案:

答案 0 :(得分:2)

这是正确的:成功回调实际上在摘要周期中被称为。如果您尝试以下

,可以看到这一点
$http.get('test.json').success(function(result) {
  $scope.$apply();
});

然后(假设GET到test.json成功),Angular会抛出一个错误,可以在控制台中看到:

 Error: [$rootScope:inprog] $digest already in progress

可以在http://plnkr.co/edit/wj4z1hDRXtK2GJnrkKuV?p=preview

看到
  

另外,$ http会触发$ digest还是$ apply?

$apply,因为它确实不知道需要检查哪些范围,它会触发全局摘要来检查它们。

答案 1 :(得分:0)

我查看了$ http的docs(行号:1083) 在下面找到这一行

  

/ **
         *回调注册到$ httpBackend():
         * - 如果需要,缓存响应          * - 解析原始$ http承诺
         * - 致电$ apply
         * /

它说回调被注册到$ httpBackend(),如果需要,它会在命令中执行以下操作缓存响应(取决于你在$ http中提供true并且它将缓存它)。然后它解析$ httppromise意味着调用成功或错误(也可以是then())取决于响应。然后它最终调用$ apply for digest cycle。

据我所知,文件$ http service bind with $ rootScope。

如果您正在考虑那么内部成功$ apply如何抛出错误,如果$ apply在它之后开始,则答案在doc本身$ rootScope。$ applyAsync,它始终运行并解析httppromise然后在此之后$ rootScope。$ apply()运行。(行:1102-1106)

希望这可以解除你的怀疑。