控制器使用ngResource方法无限调用

时间:2013-06-21 12:11:41

标签: angularjs angular-resource

我决定通过制作一个简单的应用程序来开始学习AngularJS。

服务器端应用程序是使用ExpressJs构建的,但下面使用的资源( / movie /:id )尚未实现,因此指向此URL将导致 404 (未找到)错误。所以只有'/'才能运作。

我想知道$资源的表现如何,所以我做了这个简单的测试:

var app = angular.module("app", ["ngResource"]);

app.factory("Movie", function ($resource) {
    return $resource("/movie/:id");
})

app.controller("MovieCtrl", function($scope, Movie) {
    $scope.test = function () {
        Movie.query();
        return 42;
    } 
});

我的模板文件:

<div ng-app="app">
    <div ng-controller="MovieCtrl">
        {{ test() }}
    </div>
</div>

正如预期的那样,渲染模板并正确显示“42”,但如果我在Chrome开发者工具中观看控制台,我会看到以下错误(也是预期的):

GET http://localhost/movie 404 (Not Found)

但是此邮件无限期打印并且永不停止,就好像我的电影资源一直试图到达 / movie ,即使经过一百次尝试它仍然会一直失败。< / p>

提前谢谢。

1 个答案:

答案 0 :(得分:2)

这是因为Movie.query()在收到服务器的响应后调用$scope.$apply()

每次调用$scope.$apply()时,angular都会执行脏检查(再次调用test,因此再次调用Movie.query())以查明是否有任何更改。这会导致无限循环。

Movie.query()移出test(),这应该有用。

让我自己说清楚 - 看看这个伪代码:

var watches = ['$scope.test()'];
var previous = {};
var values = {};

$rootScope.$apply = function(){
  previous = values;
  values = {};
  var dirty = false;  
  for (var i =0;i<watches.length;i++){
      var expression = watches[i];
      values[expression] = value = eval(expression);
      if(value!=previous)dirty=true;
  }
  if(dirty)$rootScope.$apply();
}

Movie.query = function(){
   setTimeout(function(){
      $rootScope.$apply();
   },300);
}

$scope.test = function(){
   Movie.query();
   return 42;
}

所以流程如下:

  1. $ scope.apply();
  2. $ scope.test();
  3. Movie.query(); - &GT; setTimeout($scope.apply,100)(回到开头);
  4. 依旧......