How can I animate sorting a list with orderBy using ng-repeat with ng-animate?

后端 未结 2 1916
谎友^
谎友^ 2020-12-02 08:25

I\'m rendering a list of objects using ng-repeat with an orderBy filter like this:

  • 2条回答
    •  死守一世寂寞
      2020-12-02 09:02

      So, even if @Alex Osborn has shown a way to do what you want in the comments, here is my attempt:

      angular.module('StackApp', []).controller('MainCtrl', function($scope) {
        'use strict';
      
        $scope.reverse = 'false';
      
        $scope.myList = [{
          id: 0,
          text: 'HTML5 Boilerplate'
        }, {
          id: 1,
          text: 'AngularJS'
        }, {
          id: 2,
          text: 'Karma'
        }, {
          id: 3,
          text: 'Hello'
        }, {
          id: 4,
          text: 'World'
        }, {
          id: 5,
          text: 'How'
        }, {
          id: 6,
          text: 'Are'
        }, {
          id: 7,
          text: 'You'
        }, {
          id: 8,
          text: '?'
        }, {
          id: 9,
          text: 'I'
        }, {
          id: 10,
          text: 'write'
        }, {
          id: 11,
          text: 'more'
        }, {
          id: 12,
          text: 'to'
        }, {
          id: 13,
          text: 'make'
        }, {
          id: 14,
          text: 'the'
        }, {
          id: 15,
          text: 'list'
        }, {
          id: 16,
          text: 'longer'
        }];
      
        $scope.$watch('reverse', function() {
          $scope.setOrder();
        });
      
        $scope.setOrder = function() {
      
          if ($scope.reverse === 'random') {
      
            var t = [];
      
            for (var i = 0; i < $scope.myList.length; i++) {
              var r = Math.floor(Math.random() * $scope.myList.length);
              while (inArray(t, r)) {
                r = Math.floor(Math.random() * $scope.myList.length);
              }
              t.push(r);
              $scope.myList[i].order = r;
            }
      
          } else {
      
            for (var i = 0; i < $scope.myList.length; i++) {
              if ($scope.reverse === 'false') {
                $scope.myList[i].order = i;
              } else {
                $scope.myList[i].order = ($scope.myList.length - 1 - i);
              }
            }
          }
        };
      
        function inArray(a, value) {
          for (var i = 0; i < a.length; i++) {
            if (a[i] === value) {
              return true;
            }
          }
          return false;
        }
      
      });
      #list {
        /* Needed, otherwise items would be at top of the page (see below) */
        position: absolute;
        /* full width, or it would look strange */
        width: 100%;
      }
      #list li {
        position: absolute;
        /* Top: 0; this will be changed for every single list item by AngularJS */
        top: 0;
        /* Item height; hold this in sync with template file */
        height: 40px;
        /*  Simple transition */
        -webkit-transition: top 0.5s ease-in-out;
        -moz-transition: top 0.5s ease-in-out;
        transition: top 0.5s ease-in-out;
      }
      
      

      Animate Order












      • {{$index}} - {{item.order}}. {{item.text}}

      So, AngularJS doesn't order the items, but it changes the CSS attribute top (ng-style="{top: ...}"). AngularJS doesn't recreate the list and we get a nice animation. :)

    提交回复
    热议问题