gpt4 book ai didi

angularjs - Angular 过滤器可以工作,但会导致 "10 $digest iterations reached"

转载 作者:行者123 更新时间:2023-12-03 07:31:06 26 4
gpt4 key购买 nike

我从后端服务器接收数据,其结构如下:

{
name : "Mc Feast",
owner : "Mc Donalds"
},
{
name : "Royale with cheese",
owner : "Mc Donalds"
},
{
name : "Whopper",
owner : "Burger King"
}

就我而言,我想“反转”列表。 IE。我想列出每个所有者,并为该所有者列出所有汉堡包。我可以通过在过滤器中使用 underscorejs 函数 groupBy 来实现此目的,然后将其与 ng-repeat 指令一起使用:

JS:

app.filter("ownerGrouping", function() {
return function(collection) {
return _.groupBy(collection, function(item) {
return item.owner;
});
}
});

HTML:

<li ng-repeat="(owner, hamburgerList) in hamburgers | ownerGrouping">
{{owner}}:
<ul>
<li ng-repeat="burger in hamburgerList | orderBy : 'name'">{{burger.name}}</li>
</ul>
</li>

这按预期工作,但当渲染列表并显示错误消息“10 $digest iterations returned”时,我得到了巨大的错误堆栈跟踪。我很难看出我的代码如何创建此消息所暗示的无限循环。有谁知道这是为什么吗?

这里是一个 plunk 的链接,代码为:http://plnkr.co/edit/8kbVuWhOMlMojp0E5Qbs?p=preview

最佳答案

发生这种情况是因为_.groupBy每次运行时都会返回对象的集合。 Angular 的 ngRepeat 没有意识到这些对象是相等的,因为 ngRepeat 通过身份来跟踪它们。新的对象导致新的身份。这使得 Angular 认为自上次检查以来某些内容发生了变化,这意味着 Angular 应该运行另一次检查(也称为摘要)。下一个摘要最终会得到另一组新的对象,因此会触发另一个摘要。不断重复直到 Angular 放弃。

消除错误的一个简单方法是确保您的过滤器每次都返回相同的对象集合(当然除非它已更改)。您可以使用 _.memoize 使用下划线轻松完成此操作。只需将过滤器函数包装在memoize中即可:

app.filter("ownerGrouping", function() {
return _.memoize(function(collection, field) {
return _.groupBy(collection, function(item) {
return item.owner;
});
}, function resolver(collection, field) {
return collection.length + field;
})
});

如果您计划对过滤器使用不同的字段值,则需要解析器函数。在上面的示例中,使用了数组的长度。更好的方法是将集合缩减为唯一的 md5 哈希字符串。

See plunker fork here 。 Memoize 会记住特定输入的结果,如果输入与之前相同,则返回相同的对象。如果值经常更改,那么您应该检查 _.memoize 是否丢弃旧结果,以避免随着时间的推移出现内存泄漏。

进一步研究,我发现 ngRepeat 支持扩展语法 ... track by EXPRESSION,这可能会有所帮助,因为它允许您告诉 Angular 查看餐馆的所有者而不是对象的身份。这将是上面内存技巧的替代方案,尽管我无法在 plunker 中测试它(可能是 track by 实现之前的旧版本 Angular?)。

关于angularjs - Angular 过滤器可以工作,但会导致 "10 $digest iterations reached",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16507040/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com