角滤波器的作品,但会导致" 10 $消化迭代达到" [英] Angular filter works but causes "10 $digest iterations reached"

查看:115
本文介绍了角滤波器的作品,但会导致" 10 $消化迭代达到"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到我的后端服务器结构类似这样的数据:

I receive data from my back end server structured like this:

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

有关我的看法,我想反转列表中。即我想列出每一位业主,并为所有者列表中的所有汉堡包。我可以通过使用underscorejs功能 GROUPBY 过滤器中,然后我与 NG-重复指令使用实现这一目标

For my view I would like to "invert" the list. I.e. I want to list each owner, and for that owner list all hamburgers. I can achieve this by using the underscorejs function groupBy in a filter which I then use in with the ng-repeat directive:

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 $消化达到迭代呈现。我有一个很难看到我怎么code创建这是由该消息暗示一个无限循环。是否有任何人知道为什么吗?

This works as expected but I get an enormous error stack trace when the list is rendered with the error message "10 $digest iterations reached". I have a hard time seeing how my code creates an infinite loop which is implied by this message. Does any one know why?

下面是与code进行普拉克的链接:<一个href=\"http://plnkr.co/edit/8kbVuWhOMlMojp0E5Qbs?p=$p$pview\">http://plnkr.co/edit/8kbVuWhOMlMojp0E5Qbs?p=$p$pview

Here is a link to a plunk with the code: http://plnkr.co/edit/8kbVuWhOMlMojp0E5Qbs?p=preview

推荐答案

这是因为 _。GROUPBY 返回集合的新的的对象,每时间运行。角的 ngRepeat 并没有意识到这些对象都是平等的,因为 ngRepeat 以跟踪它们的标识的。新的对象会导致新的身份。这使得角度认为自从上​​次检查,这意味着角应该运行另一个检查(又称为消化)的东西发生了变化。接下来摘要结束获得又一组新的对象,并且因此另一个摘要被触发。该重复,直到角放弃。

This happens because _.groupBy returns a collection of new objects every time it runs. Angular's ngRepeat doesn't realize that those objects are equal because ngRepeat tracks them by identity. New object leads to new identity. This makes Angular think that something has changed since the last check, which means that Angular should run another check (aka digest). The next digest ends up getting yet another new set of objects, and so another digest is triggered. The repeats until Angular gives up.

摆脱错误的一个简单的方法是确保你的过滤器返回的对象每次(当然,除非它已经改变)相同的集合。您可以使用 _以下划线做到这一点很容易。memoize的。只是包装过滤功能memoize的:

One easy way to get rid of the error is to make sure your filter returns the same collection of objects every time (unless of course it has changed). You can do this very easily with underscore by using _.memoize. Just wrap the filter function in 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哈希值的字符串。

A resolver function is required if you plan to use different field values for your filters. In the example above, the length of the array is used. A better be to reduce the collection to a unique md5 hash string.

这里见plunker叉。 memoize的会记住特定输入的结果和返回相同的对象,如果输入是和以前一样。如果值变化频繁,虽然那么你应该检查 _。memoize的丢弃旧的结果,以避免在一段时间内存泄漏。

See plunker fork here. Memoize will remember the result of a specific input and return the same object if the input is the same as before. If the values change frequently though then you should check if _.memoize discards old results to avoid a memory leak over time.

调查远一点我看到 ngRepeat 支持扩展语法 ...轨道由EX preSSION ,这可能会有帮助某种程度上允许你告诉角度看餐厅,而不是对象的身份所有者。这将是对记忆化替代诱骗以上,虽然我无法管理,以测试它在plunker(由在轨道可能旧版本从角开始实施?)

Investigating a bit further I see that ngRepeat supports an extended syntax ... track by EXPRESSION, which might be helpful somehow by allowing you to tell Angular to look at the owner of the restaurants instead of the identity of the objects. This would be an alternative to the memoization trick above, though I couldn't manage to test it in the plunker (possibly old version of Angular from before track by was implemented?).

这篇关于角滤波器的作品,但会导致&QUOT; 10 $消化迭代达到&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆