如何使用带有 ng-animate 的 ng-repeat 对按顺序排序的列表进行动画处理? [英] How can I animate sorting a list with orderBy using ng-repeat with ng-animate?

查看:22
本文介绍了如何使用带有 ng-animate 的 ng-repeat 对按顺序排序的列表进行动画处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ng-repeatorderBy 过滤器渲染一个对象列表,如下所示:

  • 我尝试对列表排序的更改进行 ng-animate 的尝试已被证明令人沮丧,不值得分享.我在这里看过Yearofmoo示例应用.

    不幸的是,这个演示并不是我想要实现的.在 orderBy 定义更改后,当将给定列表项放置在新订单中时,我需要为给定列表项的 X 位置设置动画.我试图通过 css 转换和绝对定位来实现这一点,但是 ng-repeat 似乎重新创建了 orderBy 上的列表项,这使得动画成为一个真正的挑战.

    1. 这可以用 ng-repeat | 实现吗?orderBy(有或没有ng-animate)?
    2. 您能建议一种方法或提供一个示例吗?

    解决方案

    所以,即使@Alex Osborn 已经在评论中展示了一种方法来做你想做的事情,这里是我的尝试:

    angular.module('StackApp', []).controller('MainCtrl', function($scope) {'使用严格';$scope.reverse = '假';$scope.myList = [{编号:0,文本:'HTML5 样板'}, {编号:1,文字:'AngularJS'}, {编号:2,文字:'业力'}, {编号:3,文字:'你好'}, {编号:4,文字:'世界'}, {编号:5,文字:'如何'}, {编号:6,文字:'是'}, {编号:7,发短信给你'}, {编号:8,文本: '?'}, {编号:9,文字:'我'}, {编号:10,文字:'写'}, {编号:11,文字:'更多'}, {编号:12,文字:'到'}, {编号:13,文字:'制作'}, {编号:14,文字:'的'}, {编号:15,文本:'列表'}, {编号:16,文字:'更长'}];$scope.$watch('reverse', function() {$scope.setOrder();});$scope.setOrder = function() {如果($scope.reverse === '随机'){var t = [];for (var i = 0; i < $scope.myList.length; i++) {var r = Math.floor(Math.random() * $scope.myList.length);而 (inArray(t, r)) {r = Math.floor(Math.random() * $scope.myList.length);}t.push(r);$scope.myList[i].order = r;}} 别的 {for (var i = 0; i < $scope.myList.length; i++) {如果($scope.reverse === '假'){$scope.myList[i].order = i;} 别的 {$scope.myList[i].order = ($scope.myList.length - 1 - i);}}}};函数 inArray(a, value) {for (var i = 0; i < a.length; i++) {如果(a[i] === 值){返回真;}}返回假;}});

    #list {/* 需要,否则项目将在页面顶部(见下文)*/位置:绝对;/* 全宽,否则看起来很奇怪 */宽度:100%;}#list li {位置:绝对;/* 顶部: 0;这将被 AngularJS 更改为每个列表项 */顶部:0;/* 物品高度;保持与模板文件同步 */高度:40px;/* 简单的过渡 */-webkit-transition:前 0.5 秒的缓入缓出;-moz-transition:前 0.5 秒缓入缓出;过渡:前 0.5 秒缓入缓出;}

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script><div ng-app="StackApp"><div ng-controller="MainCtrl"><h1>动画顺序</h1><form action=""><label for="reverse">reverse = true</label><br><input type="radio" value="true" name="reverse" ng-model="reverse"><br><br><label for="reverse">reverse = false</label><br><input type="radio" value="false" name="reverse" ng-model="reverse"><br><br><label for="reverse">reverse = 随机(点击下方按钮再次随机播放)</label><br><input type="radio" value="random" name="reverse" ng-model="reverse"></表单><br><br><input type="button" ng-click="reverse = 'random';setOrder()" value="setOrder()"><br><br><ul id="list" ng-style="{height: ((myList.length * 40) + 'px')}"><li ng-repeat="item in myList" ng-style="{top: ((item.order * 40) + 'px')}">{{$index}} - {{item.order}}.{{item.text}}
  • 因此,AngularJS 不会对项目进行排序,但它会更改 CSS 属性 top (ng-style="{top: ...}").AngularJS 不会重新创建列表,我们得到了一个很好的动画.:)

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

    <li class="list-item" ng-repeat="item in items | orderBy:predicate:reverse">

    My attempts to ng-animate a change in sorting of the list have proven frustrating and aren't worth sharing. I have seen the Yearofmoo example app here.

    Unfortunately this demonstration is not quite what I'm trying to achieve. I need to animate the X position of a given list item when it is placed in a new order after the orderBy definition changes. I have tried to accomplish this with css transitions and absolute positioning, but ng-repeat seems to recreate the list items on orderBy making animation a real challenge.

    1. Is this possible with ng-repeat | orderBy (with or without ng-animate)?
    2. Can you suggest an approach or provide an example?

    解决方案

    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;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
    <div ng-app="StackApp">
      <div ng-controller="MainCtrl">
        <h1>Animate Order</h1>
        <form action="">
          <label for="reverse">reverse = true</label>
          <br>
          <input type="radio" value="true" name="reverse" ng-model="reverse">
          <br>
          <br>
          <label for="reverse">reverse = false</label>
          <br>
          <input type="radio" value="false" name="reverse" ng-model="reverse">
          <br>
          <br>
          <label for="reverse">reverse = random (click button below to shuffle again)</label>
          <br>
          <input type="radio" value="random" name="reverse" ng-model="reverse">
        </form>
        <br>
        <br>
        <input type="button" ng-click="reverse = 'random';setOrder()" value="setOrder()">
        <br>
        <br>
        <ul id="list" ng-style="{height: ((myList.length * 40) + 'px')}">
          <li ng-repeat="item in myList" ng-style="{top: ((item.order * 40) + 'px')}">{{$index}} - {{item.order}}. {{item.text}}</li>
        </ul>
      </div>
    </div>

    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. :)

    这篇关于如何使用带有 ng-animate 的 ng-repeat 对按顺序排序的列表进行动画处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    其他开发最新文章
    热门教程
    热门工具
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆