如何使用 ng-repeat 循环遍历函数返回的项目? [英] How to Loop through items returned by a function with ng-repeat?

查看:25
本文介绍了如何使用 ng-repeat 循环遍历函数返回的项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想重复创建div,items是一个函数返回的对象.但是以下代码报告错误:已达到 10 次 $digest() 迭代.中止!jsfiddle 在这里:http://jsfiddle.net/BraveOstrich/awnqm/

<div ng-repeat="getEntities() 中的实体">你好{{entity.id}}!

解决方案

简短回答:你真的需要这样的功能还是你可以使用属性?http://jsfiddle.net/awnqm/1/

长答案

为简单起见,我将仅描述您的情况 - 对象数组的 ngRepeat.另外,我会省略一些细节.

AngularJS 使用脏检查来检测变化.当应用程序启动时,它运行 $digest 用于 $rootScope.$digest 将对 scope 的层次结构进行深度优先遍历.所有范围都有手表列表.每个手表都有最后一个值(最初是 initWatchVal).对于所有手表的每个范围 $digest 运行它,获取当前值 (watch.get(scope)) 并将其与 watch.last 进行比较.如果当前值不等于 watch.last(始终用于第一次比较)$digestdirty 设置为 true.如果 dirty == true $digest$rootScope 开始另一个深度优先遍历,则当所有范围都被处理时.$digest 在dirty == false 或遍历次数== 10 时结束.在后一种情况下,错误10 $digest() 迭代达到".将被记录.

现在关于 ngRepeat.对于每个 watch.get 调用,它存储集合中的对象(返回 getEntities 的值),并在缓存中存储附加信息(HashQueueMap by hashKey).对于每个 watch.get 调用,ngRepeat 尝试从缓存中通过其 hashKey 获取对象.如果它在缓存中不存在,ngRepeat 将它存储在缓存中,创建新的作用域,在其上放置对象,创建 DOM 元素,.

现在关于 hashKey.通常 hashKey 是由 nextUid().但它可以是函数.hashKey 生成后保存在对象中,以备将来使用.

为什么你的例子会产生错误:函数 getEntities() 总是返回带有新对象的数组.这个对象没有 hashKey 并且不存在于 ngRepeat 缓存中.因此,每个 watch.get 上的 ngRepeat 都会为它生成新的作用域,并为 {{entity.id}} 生成新的 watch.这个手表在第一个 watch.getwatch.last == initWatchVal.所以 watch.get() != watch.last.所以 $digest 开始新的遍历.所以 ngRepeat 用新的手表创建新的作用域.所以......在 10 次遍历后你会得到错误.

如何解决

  1. 不要在每次 getEntities() 调用时创建新对象.
  2. 如果您需要创建新对象,您可以为它们添加 hashKey 方法.有关示例,请参阅本主题.

希望了解 AngularJS 内部原理的人会在我做错了什么时纠正我.

I want to create divs repeatedly, the items is objects returned by a function. However the following code report errors: 10 $digest() iterations reached. Aborting! jsfiddle is here: http://jsfiddle.net/BraveOstrich/awnqm/

<body ng-app>
  <div ng-repeat="entity in getEntities()">
    Hello {{entity.id}}!
  </div>
</body>

解决方案

Short answer: do you really need such function or you can use property? http://jsfiddle.net/awnqm/1/

Long answer

For simplicity I will describe only your case - ngRepeat for array of objects. Also, I'll omit some details.

AngularJS uses dirty checking for detecting changes. When application is started it runs $digest for $rootScope. $digest will do depth-first traversal for scope's hierarchy. All scopes have list of watches. Each watch has last value (initially initWatchVal). For each scope for all watches $digest runs it, gets current value (watch.get(scope)) and compares it to watch.last. If current value is not equal to watch.last (always for first compare) $digest sets dirty to true. When all scopes are processed if dirty == true $digest starts another depth-first traversal from $rootScope. $digest ends when dirty == false or number of traversals == 10. In the latter case, the error "10 $digest() iterations reached." will be logged.

Now about ngRepeat. For each watch.get call it stores objects from collection (returning value of getEntities) with additional information in cache (HashQueueMap by hashKey). For every watch.get call ngRepeat tries to get object by its hashKey from cache. If it does not exist in cache, ngRepeat stores it in cache, creates new scope, puts object on it, creates DOM element, etc.

Now about hashKey. Usually hashKey is unique number generated by nextUid(). But it can be function. hashKey is stored in object after generating for future use.

Why your example generates error: function getEntities() always returns array with new object. This object doesn't have hashKey and doesn't exist in ngRepeat cache. So ngRepeat on each watch.get generates new scope for it with new watch for {{entity.id}}. This watch on first watch.get has watch.last == initWatchVal. So watch.get() != watch.last. So $digest starts new traverse. So ngRepeat creates new scope with new watch. So ... after 10 traverses you get error.

How you can fix it

  1. Do not create new objects on every getEntities() call.
  2. If you need to create new objects you can add hashKey method for them. See this topic for examples.

Hope people who know AngularJS internals will correct me if I'm wrong in something.

这篇关于如何使用 ng-repeat 循环遍历函数返回的项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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