我正在使用角度构建一个来自JSON API调用的数据表。我不得不使用嵌套的ngRepeat但是我看到奇怪的结果,当行有几个空字符串时,整个表行都会丢失。
我可以用下面的插件重现。 http://plnkr.co/edit/VCzzzPzfgJ95HmC2f83P?p=preview
<script>
function MyController($scope){
$scope.test = {"rows":[
["one","two","three"],
["one","two","three"],
["one","","three"],
["one","",""],
["","two",""],
["","","three"],
["one","two","three"],
["one","two","three"],
]};};
</script>
<div ng-app ng-controller="MyController">
<table>
<tr ng-repeat="(key,ary) in test.rows">
<td>{{key}}</td>
<td ng-repeat="value in ary">{{value}}</td>
</tr>
</table>
</div>
请注意,当数组有两个空字符串时,嵌套的ngRepeat似乎失败。
我生气了吗?对此有解释吗?答案 0 :(得分:9)
是。您需要使用track by $index
,因为您正在重复基元,或将其转换为对象数组。理由是ng-repeat为每个迭代值创建唯一的id $$hashkey
(并附加到重复的对象作为属性),如果它是一个对象(除非你指定某些东西作为track by)。
在你的情况下,你有原语,所以它不能附加一个属性本身,所以它试图考虑重复的值作为标识符,并在你有多个空字符串迭代时发现重复。当您重复多个对象的数组未定义或为null时,您会看到相同的效果。
因此,在这种情况下,您可以按$index
使用跟踪。因此,索引会跟踪重复的项目。
<td ng-repeat="value in ary track by $index">{{value}}</td>
<强> Demo 强>
更好的选择总是将其转换为对象数组,这样您就不会遇到这些问题。如果您拥有唯一标识重复元素的属性(例如id
),则可以将其设置为track by
属性。当您重新绑定数组(或刷新数组)时,angular使用跟踪的标识符来确定是否需要从DOM中删除该元素并重新创建它或只刷新已存在的元素。在使用项目列表刷新列表的许多情况下,总是希望使用轨道与对象上的标识符重复以提高性能。