Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 如何使用ng repeat遍历函数返回的项?_Angularjs - Fatal编程技术网

Angularjs 如何使用ng repeat遍历函数返回的项?

Angularjs 如何使用ng repeat遍历函数返回的项?,angularjs,Angularjs,我想重复创建div,项是由函数返回的对象。但是,以下代码会报告错误: 已达到10$digest()迭代次数。流产!JSFIDLE在这里: 你好{{entity.id}! 这是一个问题,并得到了以下响应: 您的getter不是幂等的,它会更改模型(每次调用时生成一个新数组)。这迫使angular继续调用它,希望模型最终会稳定下来,但它从未这样做angular放弃并抛出异常 getter返回的值相等但不相同,这就是问题所在 如果将阵列移到主控制器外,则可以看到此行为消失: var数组=[{id:'

我想重复创建div,项是由函数返回的对象。但是,以下代码会报告错误: 已达到10$digest()迭代次数。流产!JSFIDLE在这里:


你好{{entity.id}!
这是一个问题,并得到了以下响应:

您的getter不是幂等的,它会更改模型(每次调用时生成一个新数组)。这迫使angular继续调用它,希望模型最终会稳定下来,但它从未这样做angular放弃并抛出异常

getter返回的值相等但不相同,这就是问题所在

如果将阵列移到主控制器外,则可以看到此行为消失:

var数组=[{id:'angularjs'}];
主要功能($scope){
$scope.getEntities=function(){return array;};
};
因为现在它每次都返回相同的对象。您可能需要重新构建模型,以使用作用域上的属性而不是函数:

我们通过将控制器方法的结果分配给属性并对其执行ng:repeat来解决这个问题


简短回答:您真的需要这样的功能还是可以使用属性

长答案

为了简单起见,我将只描述您的case-ngRepeat对象数组。另外,我将省略一些细节

AngularJS用于检测更改。当应用程序启动时,它会运行一段时间
$digest
将对进行深度优先遍历。所有示波器都有手表列表。每个手表都有最后一个值(最初为
initWatchVal
)。对于所有手表的每个作用域,
$digest
运行它,获取当前值(
watch.get(scope)
),并将其与
watch.last
进行比较。如果当前值不等于
watch.last
(始终用于第一次比较)
$digest
dirty
设置为
true
。处理所有作用域时,如果
dirty==true
$digest
$rootScope
开始另一次深度优先遍历<代码>$digest在dirty==false或遍历次数==10时结束。在后一种情况下,将记录错误“10$digest()iterations reacted.”

现在关于
ngRepeat
。对于每个
watch.get
调用,它存储来自集合的对象(返回
getEntities
)以及缓存中的附加信息(通过
hashKey
)。对于每个
watch.get
call
ngRepeat
尝试通过其
hashKey
从缓存中获取对象。若它不存在于缓存中,
ngRepeat
将其存储在缓存中,创建新的作用域,将对象放在其上,创建DOM元素

现在开始。通常,
hashKey
是由生成的唯一数字。但也有可能<代码>哈希键在生成后存储在对象中,以备将来使用

示例生成错误的原因:函数
getEntities()
始终返回带有新对象的数组。此对象没有
hashKey
,并且不存在于
ngRepeat
缓存中。因此,
ngRepeat
对每个
watch.get
使用
{{entity.id}
的新watch为其生成新的作用域。第一次
watch.get
上的此手表具有
watch.last==initWatchVal
。所以
watch.get()!=观察。最后一次
。因此,
$digest
开始新的遍历。因此,
ngRepeat
使用新手表创建新范围。所以经过10次遍历后,您将得到错误

如何修复它

  • 不要在每次调用
    getEntities()
    时创建新对象
  • 如果需要创建新对象,可以为它们添加
    hashKey
    方法。有关示例,请参见

  • 希望了解AngularJS内部结构的人能够纠正我在某些方面的错误。

    在repeat之外初始化数组

    <body ng-app>
       <div ng-init="entities = getEntities()">
           <div ng-repeat="entity in entities">
               Hello {{entity.id}}!
           </div>
       </div>
    </body>
    
    
    你好{{entity.id}!
    
    基于@przno注释

    <body ng-app>
      <div ng-repeat="item in t = angular.equals(t, getEntities()) ? t : getEntities()">
        Hello {{item.id}}!
      </div>
    </body>
    
    
    你好{{item.id}}!
    

    顺便说一句,Artem Andreev提出的第二个解决方案不适用于Angular 1.1.4及更高版本,而第一个解决方案不能解决问题。因此,我现在恐怕这是一个功能上没有缺点的不那么尖锐的解决方案

    +1谢谢你。我有同样的问题,不能使用静态属性$$hashKey应该记录在手册IMO的ngRepeat页面上。你知道从1.1.3到1.1.4的变化影响了这一点吗?在1.1.4之前,这实际上是有效的。变更日志中没有关于它的任何内容,我无法解释出区别是什么。当前的行为是有道理的。另外,如果可以,请检查一下:我不确定我的答案是否正确。因此,按照
    的建议,不要在每个getEntities()上创建新对象调用。
    它可以很容易地修复,如下所示:
    如果数组发生变化,
    getEntities()
    始终返回相同的数组,则我前面的注释中的解决方案会起作用,在
    ng repeat
    中,如果函数的参数在每次迭代中都发生更改,则使用属性可能是唯一的方法。如果
    getEntities()
    在程序的生命周期中返回不同的内容,则这不起作用。例如,假设
    getEntities()
    触发
    $http.get
    。当get finally resolve(您进行了AJAX调用)时,
    实体
    将已经初始化。从angular docs
    中,ngInit的唯一适当用途是对ngRepeat的特殊属性进行别名。除此之外,您应该使用控制器而不是ngInit来初始化作用域上的值。
    我认为主要的一点是通过任何方式“在repeat之外初始化数组”。。。还有@Nighto good call on promises你是说item.id吗?如果entity.id是您的意思,您能解释一下吗
    <body ng-app>
      <div ng-repeat="item in t = angular.equals(t, getEntities()) ? t : getEntities()">
        Hello {{item.id}}!
      </div>
    </body>