我是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需要检查所有列表项。不过,我很困惑。这样做的正确方法是什么?
答案 0 :(得分:6)
问题与在绑定中使用函数有关(插值{{}})。由于其性质,angularjs不断观察$ scope(视图模型)的变化。因此,如果您不小心,您可以绑定到始终返回对象的新/不同实例的函数。这会触发一个无限循环,该角度将angular标识为错误并禁用绑定以避免stackoverflow。如果说您更改了将返回的客户存储到本地变量的功能,则可以避免此问题。
这是一个完整的代码段。
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;