AngularJS - 错误:[$ rootscope:infdig] 10 $ digest()迭代达成

时间:2014-12-15 13:44:55

标签: angularjs

我是AngularJS的新手,遇到了问题。

我有一个通过$ http GET请求检索到的JSON发票数组,该请求正在这里循环:

  <a ng-repeat="invoice in invoices" href="#" class="list-group-item">
    {{ invoice[data]["TxnDate"][0] }} -
    {{ invoice[data]["DocNumber"][0] }} - 
    ${{ invoice[data]["TotalAmt"][0] }} - 
    {{ getCustomer(invoice[data]["Id"][0]) }}

    <i class="fa fa-chevron-right pull-right"></i>
    <i class="pull-right">Edit</i>
  </a>

问题是发票数组不存储客户的参考编号以外的任何客户信息。

因此,我创建了一个名为getCustomer的函数,该函数通过参考编号查询我的API以获取客户的姓名。

$scope.getCustomer = function(id) {

    var customer_id = id.match(/\d+/)[0];

    $http.post('/customers', customer_id).success(function(response) {
        console.log(response);
    });

};

问题是我收到此错误:

error: [$rootscope:infdig] 10 $digest() iterations reached. aborting! watchers fired in the last 5 iterations: []

稍后,我会想出一个更有效的方法来做到这一点,但我很想知道导致这个错误的原因是什么?

在做了一些研究后,我认为这与以下事实有关:一旦其中一个列表项中的数据发生变化,AngularJS需要检查所有列表项。不过,我很困惑。这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:6)

问题与在绑定中使用函数有关(插值{{}})。由于其性质,angularjs不断观察$ scope(视图模型)的变化。因此,如果您不小心,您可以绑定到始终返回对象的新/不同实例的函数。这会触发一个无限循环,该角度将angular标识为错误并禁用绑定以避免stackoverflow。如果说您更改了将返回的客户存储到本地变量的功能,则可以避免此问题。

这是一个完整的代码段。

&#13;
&#13;
var app = angular.module('main', []);

app.controller('MainCtrl', function($scope, $http, $q) {
  $scope.invoices = [
    { Id: "1", TxnDate: new Date(2014, 6, 26), DocNumber: "I001234", TotalAmt: 200.34 }, 
    { Id: "2", TxnDate: new Date(2014, 8, 2), DocNumber: "I000021", TotalAmt: 530.34 }, 
    { Id: "3", TxnDate: new Date(2014, 11, 15), DocNumber: "I000023", TotalAmt: 123 },  
    { Id: "4", TxnDate: new Date(2014, 12, 11), DocNumber: "I000027", TotalAmt: 5000 },  
  ];
  
  var testUrl = 'http://echo.jsontest.com/company/AKME/firstName/John/lastName/Doe';
  var _customerCache = {};
  $scope.customerCache = _customerCache;
  $scope.getCustomer = function(id) {
    var deferred = $q.defer(); // defer
    if (_customerCache[id])
        return deferred.resolve(_customerCache[id]);
    
    var customer_id = id.match(/\d+/)[0]; 

    $http.get(testUrl + customer_id + '/id/'+ customer_id).success(function(response) {
        console.log(response);
        _customerCache[id] = response;
        deferred.resolve(response);
    });
    return deferred.promise;
};
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div  ng-app="main"  ng-controller="MainCtrl">
  <ul>
    <li ng-repeat="invoice in invoices" ng-init="getCustomer(invoice.Id)">
    <a href="#" class="list-group-item">
      {{ invoice.TxnDate | date }} -
      {{ invoice.DocNumber }} - 
      {{ invoice.TotalAmt | currency }}
      {{ customerCache[invoice.Id].firstName }} {{ customerCache[invoice.Id].lastName }}
    </a>
    </li>
  </ul>
  <span>customers via http</span>
  <ul>
    <li ng-repeat="cust in customerCache">
      {{cust}}
    </li>
  </ul>
<div>
&#13;
&#13;
&#13;