我有一个项目列表,每个项目都有一个唯一的 id
$scope.arr = [{val:0,id:'a'},{val:1,id:'b'},{val:2,id:'c'}];
每个项目都根据它们的 $index 进行绝对定位
<div class="item" ng-repeat="item in arr track by item.id"
ng-style="getAbsPos($index)" >{{item.id}}</div>
我只想交换数组中的 arr[0]
和 arr[2]
,并显示这个 Action 的移动动画 .事实证明这很困难。
我假设这个 css 可以工作,因为列表是由 id 跟踪的
.item{
transition:all 3000ms;
}
但不知何故 angular 决定仅移动其中一个项目的 dom 并重新创建另一个(为什么?!)。结果,只有一个项目是动画的。
=问题=
是否有解决此问题的解决方案,以便两个项目在交换时都具有动画效果?谢谢。
(必须实际交换项目在数组中的位置,以便始终可以通过正确的索引轻松访问它)
= 查看 Plunker 演示 =
最佳答案
在尝试之后,我确实找到了一个非常 hacky 的解决方案,它确实改变了数组中的项目顺序:
=想法=
正如 Zack 和其他许多人所建议的,我们在每个项目中记录显示位置(item.x),用它来确定 dom 位置
<div class="item" ng-repeat="item in arr track by item.id" ng-style="getAbsPos(item.x)" >{{item.id}}</div>
交换时,先对数组重新排序,因为dom位置是由item.x决定的,而不是$index,不会触发动画;
var a= arr[0]; var c = arr[2]; arr[0] = c; arr[2] = a;
以异步方式交换两个项目的 item.x 值(使用
$timeout
),因此 Angular 将第 2 步和第 3 步视为两个单独的 dom 更改,只有第 3 步会触发动画。$timeout(function(){ var tempX = a.x; a.x = c.x; c.x = tempX; },10)
这可能会在执行批量交换操作时产生一些问题。但是对于用户触发的简单的两个项目交换(我的用例),它似乎工作正常。
请告诉我是否有更好的解决方案,谢谢。
=Plunker 演示=
关于javascript - AngularJS:用动画交换 ng-repeater 中的两个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23985029/