Ed *_*ffe 6 javascript angularjs angularjs-ng-repeat
我正在构建一个具有一种"播放列表"的应用程序.这表示一个ng-repeated自定义指令ng-repeat = "element in playlist"
因为我想允许用户在播放列表中重复使用相同的元素两次,所以我尝试使用track by $index添加.
现在,令人困惑的是:当我从播放列表中删除一个元素时(我有一个removeElement(index)基本上包含这样的东西的函数:
$scope.removeElement = function(index){
$scope.playlist.splice(index, 1);
}
Run Code Online (Sandbox Code Playgroud)
发生了一些奇怪的事情:元素被正确删除$scope.playlist,但由于某种原因,视图没有正确更新.最后一个元素似乎被删除了.
此外,我无法正确地重新排序数组中的元素.
当我删除track by $index这个问题消失,所以我认为这是因为当你从数组中删除一个项目时,如果你只是查看索引,那么看起来你刚刚删除了最后一个.
但是行为很奇怪,因为已经正确删除了被盗的内容 - 请参阅此plunker
编辑:上面的链接已被修改,以更好地显示问题,并显示我确定的答案.
这个问题也经过了轻微编辑,以便更清楚地了解我的情况.KayakDave下面的答案仍然是正确的,但更适合一系列原语(我原来的plunker特色).
TL; DR:如何在ng-repeat不牺牲控制位置或正确删除元素的能力的情况下将重复元素放入其中?
使用的一个重要性能优势track by是Angular不会触及跟踪表达式未发生变化的任何DOM元素.对于长ng-repeat列表而言,这是一个巨大的性能改进,也是增加列表的原因之一track by.
性能优化是您所看到的根源.
当你使用时$index,track by你要告诉ng-repeat它将$index第一次运行时创建的每个DOM元素与它的position()联系起来ng-repeat.
所以颜色样式为红色的元素标记为0,橙色1,黄色2 ......最后标记为靛蓝5.
当您删除一个颜色时,Angular会查看您告诉它要跟踪的索引并看到您的索引#5更长(因为您的列表比以前更短).因此,它删除了标记为5-的DOM元素,其具有"indigo"的颜色样式.您仍然有索引#2,因此颜色为黄色的元素会保留.
令人困惑的是,由于数据绑定,DOM元素内的文本确实会更新.因此,当您删除"黄色"时,带有黄色的DOM元素会将文本设置为"绿色".
简而言之,您所看到的是ng-repeat将DOM元素保留为黄色样式,因为它的跟踪值(2)仍然存在,但数据绑定已更新该元素内的文本.
要添加具有相同颜色的多个条目,您需要将唯一标识符添加到您用于的每个条目track by.一种方法是为每个条目使用键值对,其中键是您的唯一标识符.像这样:
$scope.colorlist = {1:'red', 2:'orange',3:'yellow',4:'green',5:'blue',6:'indigo',7:'yellow'};
Run Code Online (Sandbox Code Playgroud)
然后track by关键如下:
<color-block ng-repeat="(key, color) in colorlist track by key" color="{{color}}" ng-transclude>
{{color}}
</color-block>
Run Code Online (Sandbox Code Playgroud)
并确保使用该键进行删除选择:
<option value="{{key}}" ng-repeat="(key,color) in colorlist">{{color}}</option>
Run Code Online (Sandbox Code Playgroud)
现在,颜色样式为黄色的DOM元素与您为"黄色"数组元素指定的键相关联.因此,当您删除"黄色"时,ng-repeat将删除正确的DOM元素,一切正常.
你可以在这里看到它的工作原理:http: //plnkr.co/edit/cFaU8WIjliRjPI6LInZ0?p = preview