AngularJS: swap two items in ng-repeater with animation

本小妞迷上赌 提交于 2019-12-05 11:48:39

After playing around, I did find a very hacky solution which does change the item order in array:

=Idea=

  1. As Zack and many other suggested, we keep a record of display position(item.x) in each item, use it to determine dom position

    <div class="item" ng-repeat="item in arr track by item.id" 
    ng-style="getAbsPos(item.x)" >{{item.id}}</div>
    
  2. when swap, reordering the array first, because dom position is determined by item.x, not $index, no animation will be triggered;

     var a= arr[0];
     var c = arr[2];
     arr[0] = c;
     arr[2] = a; 
    
  3. swap the item.x value of the two items in async manner (using $timeout), so angular treats step 2 and 3 as two separated dom changes, and only step 3 will trigger animation.

     $timeout(function(){
         var tempX = a.x;
     a.x = c.x;
     c.x = tempX;           
     },10)   
    

This may create some problems when batch swap operations are performed. But for user triggered simple two items swap (my use case), it seems works just ok.

Let me know if there is a better solution, thanks.

=Plunker demo=

http://plnkr.co/edit/Vjj9qCcoqMCyuOhNYKKY?p=preview

One idea would be to use your own left marker, rather than $index. Here is an example using a directive that watches your objects .left attribute. In this scenario you could use the .left to reorder the actual array at some point if you need to post it to a server or something. Here is an accompanying JSFIDDLE.

HTML

<div class="item" ng-repeat="item in list" move-to="item.left">{{item.id}} / {{$index}}</div>

module.controller('myCtrl', function($scope) { 
$scope.list = [
        {val:0, id:'a', left: 0},
        {val:1, id:'b', left: 100},
        {val:2, id:'c', left: 200}
    ];

    $scope.swap = function() {
        var a_left = $scope.list[0].left
        $scope.list[0].left = $scope.list[2].left;
        $scope.list[2].left = a_left;
    }
}) 

.directive('moveTo', function() {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs) {
            scope.$watch(attrs.moveTo, function(newVal) {
                elem.css('left', newVal + "px"); 
            });
        }
    }
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!