2013-05-08 13 views
29

Böyle bir orderBy filtreli ng-repeat kullanarak nesnelerin listesini render ediyorum: içinng-animate ile ng-repeat kullanarak orderBy ile bir listeyi sıraya koyabilir miyim?

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

denemelerim listesinin sıralama değişikliği ng-animasyon sinir bozucu kanıtlanmış ve değer paylaşımı olmayan var . Yearofmoo örnek uygulamasını here gördüm.

Maalesef bu gösteri, elde etmeye çalıştığım şey değil. orderBy tanımındaki değişiklikten sonra yeni bir sıraya yerleştirildiğinde, belirli bir liste öğesinin X konumunu canlandırma ihtiyacım var. Bunu css geçişleri ve mutlak konumlandırma ile gerçekleştirmeye çalıştım, ancak ng-repeat, animasyonun gerçek bir meydan okuma yapmasını sağlayan orderBy'daki liste öğelerini yeniden oluşturuyor gibi görünüyor.

  1. ng-repeat | orderBy (veya ng-animate olmadan) ile bu mümkün mü?
  2. Bir yaklaşım önerebilir veya örnek verebilir misiniz? @Alex Osborn burada benim girişimi, yorumlardaki istediğini yapmanın bir yolunu göstermiştir bile
+5

Ben bu sorunu geldi ama bir çözüm oluşturmak için olmadı, yoksa örneklerle uygun bir cevap verdiğine - ancak Planladığım çözüm, listenin bir kopyasına (yani bir denetleyiciye) filtre uygulamak, öğenin yeni dizinini bulmak ve ardından öğeyi bu dizine taşımak için animasyon uygulamaktı. Haklısınız - filtre + ng tekrarı sadece listeyi yeniden oluşturur. Asıl istediğin şey, animasyonu işleyen konumun ayrı ayrı belirlenmesidir. –

+0

Bu çözümden korkuyordum - teşekkürler! – Casey

+0

@AlexOsborn Bunu bir cevap olarak göndermelisiniz. Bana yardımcı oldu! –

cevap

41

Yani,: Yani

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>

, angularjs değil Öğeleri sipariş edin, ancak CSS özniteliğini top (ng-style="{top: ...}") değiştirir. AngularJS listeyi yeniden oluşturmaz ve güzel bir animasyon alırız. :)

+0

Bunu bir araya getirdiğiniz için teşekkürler! – Casey

+6

Bu çözümün, DOM'deki sıralarını değil, üstbilgi özelliklerini (yalnızca çalışmasının nedeni muhtemelen - Angular tarafından kaldırılmamış ve okunmamış) değiştirdiğine dikkat edin. Bu, görsel açıdan önemli olmasa da, erişilebilirlik için kötüdür: ekran okuyucuları olan kör kullanıcılar her zaman ilk oluşturma işleminin orijinal sırasını alır. Bu konudaki WCAG kılavuzuna bakın: http://www.w3.org/TR/WCAG20-TECHS/C27.html – denisw

+0

Bunun yerine Çok fazla Kod yazarak doğrudan javascript'in reverse() işlevini kullanabilirsiniz. var list = Şirket listesi []; reverselist = list.ters(); ng-repeat = "Reverselist öğesinde" –

11

AndreM96'nın listeyi ızgara olarak görüntülemesine izin vermek için yanıtını genişlettim.

angular.module('StackApp', []).config(function($routeProvider) { 
 

 
    'use strict'; 
 

 
    $routeProvider 
 
    .when('/', { 
 
     template: '<h1>Animate Order</h1>' + 
 
     '<form action="">' + 
 
     '<input type="radio" value="true" name="order" ng-model="order">' + 
 
     '<label for="order">reverse</label><br><br>' + 
 

 
     '<input type="radio" value="false" name="order" ng-model="order">' + 
 
     '<label for="order">normal</label><br><br>' + 
 

 
     '<input type="radio" value="random" name="order" ng-model="order">' + 
 
     '<label for="order">random (click button below to shuffle again)</label><br>' + 
 

 
     '</form>' + 
 
     '<input type="button" ng-click="order = \'random\';setOrder()" value="randomize">' + 
 
     '<br><br>' + 
 
     '<ul id="list" ng-style="{height: ((myList.length * 90) + \'px\')}">' + 
 
     '<li ng-repeat="item in myList" ng-style="{top: ((item.row * 90) + \'px\'), left: ((item.column * 90) + \'px\')}">{{$index}} - {{item.order}}. {{item.text}}</li>' + 
 
     '</ul>', 
 
     controller: 'MainCtrl' 
 
    }) 
 
    .otherwise({ 
 
     redirectTo: '/' 
 
    }); 
 

 
}); 
 

 
angular.module('StackApp').controller('MainCtrl', function($scope) { 
 
    'use strict'; 
 

 
    $scope.order = '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('order', function() { 
 
    $scope.setOrder(); 
 
    }); 
 

 
    $scope.setOrder = function() { 
 

 
    var i; 
 

 
    if ($scope.order === 'random') { 
 
     var t = []; 
 
     for (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 if ($scope.order === 'false') { 
 
     for (i = 0; i < $scope.myList.length; i++) { 
 
     $scope.myList[i].order = i; 
 
     } 
 
    } else { 
 
     for (i = 0; i < $scope.myList.length; i++) { 
 
     $scope.myList[i].order = ($scope.myList.length - 1 - i); 
 
     } 
 
    } 
 

 
    calcGridPosition(); 
 
    }; 
 

 
    function inArray(a, value) { 
 
    for (var i = 0; i < a.length; i++) { 
 
     if (a[i] === value) { 
 
     return true; 
 
     } 
 
    } 
 
    return false; 
 
    } 
 

 
    function calcGridPosition() { 
 
    for (var i = 0; i < $scope.myList.length; i++) { 
 
     var item = $scope.myList[i]; 
 

 
     // columns, left-to-right, top-to-bottom 
 
     var columns = 5; 
 
     item.column = item.order % columns; 
 
     item.row = Math.floor(item.order/columns); 
 

 
     // rows, top-to-bottom, left-to-right 
 
     // var rows = 3; 
 
     // item.column = Math.floor(item.order/rows); 
 
     // item.row = item.order%rows; 
 
    } 
 
    } 
 

 
});
#list { 
 
    position: absolute; 
 
    width: 100%; 
 
    list-style-type: none; 
 
    padding-left: 0; 
 
} 
 

 
#list li { 
 
    position: absolute; 
 
    height: 70px; 
 
    width: 70px; 
 
    background: #ddd; 
 
    -webkit-transition: all 2.5s ease-in-out; 
 
    -moz-transition: all 2.5s ease-in-out; 
 
    transition: all 2.5s ease-in-out; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script> 
 
<main ng-app="StackApp"> 
 
    <div class="container" ng-view></div> 
 
</main>

JSBin Demo

enter image description here

+1

kod nerede? – krivar

+8

Yukarıdaki 'demoyu görüntüle' bağlantısını tıklayın ve tarayıcınızın sağ üst köşesinde 'js bin içinde düzenle' düğmesini bulacaksınız. Not: Sorunun kulağa kaba geliyor. Bir dahaki sefere daha iyi soracak olursanız sevinirim. Teşekkürler. – robro

+0

hey, cevabım ve yorumuma geri bildirim için teşekkürler. Bir dahaki sefere daha çok ilgileneceğim. – krivar

İlgili konular