AngularJS: Error: [$rootScope:infdig] - Call function in AngularJS view
AngularJS: Error: [$rootScope:infdig] - Call function in AngularJS view
我写了一个包含这个功能的控制器:
$scope.getItemName = function (id) {
sgcdata.get('item', {
_id: id
}).then(function (dataItem) {
return dataItem[0].brand_name + " " + dataItem[0].reference;
});
}
并且在视图中:
<li ng-repeat="itemCart in connectedUser.cart track by $index" class="list-group-item">
<span class="badge cursorpointer" ng-click="removeFromCart(itemCart)">X</span>
<a href="#">{{ getItemName(itemCart) }}</a>
</li>
当我这样做时,我得到一个无限循环 ($rootScope:infdig
)。
sgcdata.get
发出 XHR 请求。
但是如果我 return 一个简单的字符串,它就可以工作:
$scope.getItemName = function (id) {
return "toto";
}
我真的不明白这是怎么回事...
感谢您的帮助。
编辑
我做了一个过滤器而不是之前的函数:
JS:
sgc.filter('getItemName', [
'sgcdata',
function (sgcdata) {
return function (id) {
sgcdata.get('item', {
_id: id
}).then(function (dataItem) {
return dataItem[0].brand_name + " " + dataItem[0].reference;
});
}
}
]);
HTML:
<li ng-repeat="itemCart in connectedUser.cart track by $index" class="list-group-item">
<span class="badge cursorpointer" ng-click="removeFromCart(itemCart)">X</span>
<a href="#">{{ itemCart | getItemName }}</a>
</li>
我不再有任何无限循环,但我无法在 ng-repeat 中获取多个值,而过滤器 return 在项目请求中。
编辑
sgcdata.get:
service.get = function (collection, filters) {
var deferred = $q.defer();
var formatRequest = function (obj) {
var str = [];
for (var p in obj) {
str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
}
if (str.length) {
return '&' + str.join('&');
} else {
return '';
}
};
$http({
method: 'GET',
url: '/v1/get/?element=' + collection.toLowerCase() + formatRequest(filters)
}).then(function (response) {
deferred.resolve(response.data);
}, function (response) {
console.error("[ FAILED ] >> " + response);
});
return deferred.promise;
}
您应该return 函数中的相同引用或值。否则事情会失控。
从 ng-repeat
HTML 模板中调用函数总是会导致 Infinite Digest
错误,因为摘要循环本身的性质。
本质上,ng-repeat
尝试渲染子节点。在子节点中,您正在调用一个函数,这会导致出现摘要。这个新的摘要导致 ng-repeat
重新开始,这导致子节点再次成为 运行,这导致另一个摘要,无穷无尽。
有几种普遍接受的方法可以解决这个问题,每种方法各有利弊。
从服务器获取原始数组时,在服务器上执行逻辑以将所有相关字段包含在原始return值中。这是非常高效的,因为您允许您的服务器完成所有繁重的工作,并且只需要对服务器进行一次调用。但是,您可能会发送仅对应用的一小部分有用的额外数据,这可能会减慢初始启动时间。
获取原始数组时,运行每个元素的函数 returned 将额外数据作为新 属性 添加到每个元素上。这是相当有效的,因为这意味着您的所有数据都是预先加载的,您只需对每个元素进行一次额外调用。这可能会遇到与您发送不常用数据相同的负面影响,如果您有许多元素需要迭代,这也会加剧初始启动速度减慢。
向 ng-repeat
添加过滤器,而不是元素,它遍历数组并 独占地 获取额外数据 =10=]。这样做的好处是仅在 ng-repeat
存在时才对服务器进行额外调用,并且不会将额外数据添加到原始数组中。但是,这些对服务器的额外调用将在 ng-repeat
更改(添加新元素、删除项目、应用其他过滤器等)时执行,这可能会导致严重的性能损失,具体取决于数据量和变化的频率。
我写了一个包含这个功能的控制器:
$scope.getItemName = function (id) {
sgcdata.get('item', {
_id: id
}).then(function (dataItem) {
return dataItem[0].brand_name + " " + dataItem[0].reference;
});
}
并且在视图中:
<li ng-repeat="itemCart in connectedUser.cart track by $index" class="list-group-item">
<span class="badge cursorpointer" ng-click="removeFromCart(itemCart)">X</span>
<a href="#">{{ getItemName(itemCart) }}</a>
</li>
当我这样做时,我得到一个无限循环 ($rootScope:infdig
)。
sgcdata.get
发出 XHR 请求。
但是如果我 return 一个简单的字符串,它就可以工作:
$scope.getItemName = function (id) {
return "toto";
}
我真的不明白这是怎么回事...
感谢您的帮助。
编辑
我做了一个过滤器而不是之前的函数:
JS:
sgc.filter('getItemName', [
'sgcdata',
function (sgcdata) {
return function (id) {
sgcdata.get('item', {
_id: id
}).then(function (dataItem) {
return dataItem[0].brand_name + " " + dataItem[0].reference;
});
}
}
]);
HTML:
<li ng-repeat="itemCart in connectedUser.cart track by $index" class="list-group-item">
<span class="badge cursorpointer" ng-click="removeFromCart(itemCart)">X</span>
<a href="#">{{ itemCart | getItemName }}</a>
</li>
我不再有任何无限循环,但我无法在 ng-repeat 中获取多个值,而过滤器 return 在项目请求中。
编辑
sgcdata.get:
service.get = function (collection, filters) {
var deferred = $q.defer();
var formatRequest = function (obj) {
var str = [];
for (var p in obj) {
str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
}
if (str.length) {
return '&' + str.join('&');
} else {
return '';
}
};
$http({
method: 'GET',
url: '/v1/get/?element=' + collection.toLowerCase() + formatRequest(filters)
}).then(function (response) {
deferred.resolve(response.data);
}, function (response) {
console.error("[ FAILED ] >> " + response);
});
return deferred.promise;
}
您应该return 函数中的相同引用或值。否则事情会失控。
从 ng-repeat
HTML 模板中调用函数总是会导致 Infinite Digest
错误,因为摘要循环本身的性质。
本质上,ng-repeat
尝试渲染子节点。在子节点中,您正在调用一个函数,这会导致出现摘要。这个新的摘要导致 ng-repeat
重新开始,这导致子节点再次成为 运行,这导致另一个摘要,无穷无尽。
有几种普遍接受的方法可以解决这个问题,每种方法各有利弊。
从服务器获取原始数组时,在服务器上执行逻辑以将所有相关字段包含在原始return值中。这是非常高效的,因为您允许您的服务器完成所有繁重的工作,并且只需要对服务器进行一次调用。但是,您可能会发送仅对应用的一小部分有用的额外数据,这可能会减慢初始启动时间。
获取原始数组时,运行每个元素的函数 returned 将额外数据作为新 属性 添加到每个元素上。这是相当有效的,因为这意味着您的所有数据都是预先加载的,您只需对每个元素进行一次额外调用。这可能会遇到与您发送不常用数据相同的负面影响,如果您有许多元素需要迭代,这也会加剧初始启动速度减慢。
向
ng-repeat
添加过滤器,而不是元素,它遍历数组并 独占地 获取额外数据 =10=]。这样做的好处是仅在ng-repeat
存在时才对服务器进行额外调用,并且不会将额外数据添加到原始数组中。但是,这些对服务器的额外调用将在ng-repeat
更改(添加新元素、删除项目、应用其他过滤器等)时执行,这可能会导致严重的性能损失,具体取决于数据量和变化的频率。