kątowe powtórzenie ng w odwrotnej kolejności


227

Jak mogę uzyskać odwrócony układ kątowy? Próbuję użyć filtru orderBy, ale do sortowania potrzeba predykatu (np. „name”):

<tr ng-repeat="friend in friends | orderBy:'name':true">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
<tr>

Czy istnieje sposób na odwrócenie oryginalnej tablicy bez sortowania. tak:

<tr ng-repeat="friend in friends | orderBy:'':true">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
<tr>

4
To jest nowy i właściwy sposób stackoverflow.com/a/16261373/988830
om471987

@QuiteNothing To jest właściwy sposób, jeśli chcesz odwrócić tablicę z wyrażeniem. W tym przypadku chodziło o to, jak uszanować tablicę bez niej .
JayQuerie.com

<tr ng-repeat = "przyjaciel w znajomych | orderBy: '- name'">
desmati

Zobacz moją odpowiedź poniżej, aby uzyskać prosty 1 wiersz i prawidłowe rozwiązanie. Nie trzeba tworzyć żadnych metod. Zastanawiam się, dlaczego ludzie robią w tym celu dodatkowe metody.
Muhammad Hassam

Zawsze używaj filtrów do zmiany ng-repeatzachowania! @Trevor Senior wykonał dobrą robotę.
Amir Savand

Odpowiedzi:


329

Sugeruję użycie niestandardowego filtra, takiego jak ten:

app.filter('reverse', function() {
  return function(items) {
    return items.slice().reverse();
  };
});

Które można następnie wykorzystać jako:

<div ng-repeat="friend in friends | reverse">{{friend.name}}</div>

Zobacz, jak działa tutaj: demonstracja plunkera


Ten filtr można dostosować do własnych potrzeb. Podałem inne przykłady podczas demonstracji. Niektóre opcje obejmują sprawdzenie, czy zmienna jest tablicą przed wykonaniem operacji odwrotnej, lub uczynienie jej bardziej łagodnym, aby umożliwić odwrócenie większej liczby rzeczy, takich jak łańcuchy.


21
Miły! Pamiętaj, że items.reverse()modyfikuje tablicę, zamiast tworzyć nową i zwracać ją.
Anders Ekdahl,

12
Dzięki! Przeoczyłem to. Wrzuciłem, slice()aby rozwiązać ten problem.
JayQuerie.com,

9
Należy dodać, if (!angular.isArray(items)) return false;aby sprawdzić, czy macie tablicę przed próbą jej odwrócenia.
szacunek TheCode

6
Musisz być bardziej defensywny w stosunku do wartości zerowej, zamiast tego użyj następujących: zwracać przedmioty? items.slice (). reverse (): [];
Chris Yeung,

5
@Chris Yeung: Nie zaleca się zwracania pustego „[]”, gdy wartość jest pusta. Lepiej zwrócić pierwotną wartość.
Siva

202

Właśnie tego użyłem:

<alert ng-repeat="alert in alerts.slice().reverse()" type="alert.type" close="alerts.splice(index, 1)">{{$index + 1}}: {{alert.msg}}</alert>

Aktualizacja:

Moja odpowiedź była dobra dla starej wersji Angulara. Teraz powinieneś używać

ng-repeat="friend in friends | orderBy:'-'"

lub

ng-repeat="friend in friends | orderBy:'+':true"

z https://stackoverflow.com/a/26635708/1782470


Uing track by, to jedyny sposób, który zadziałał dla mnie

@delboud powinieneś używać track po zamówieniu Przez:ng-repeat="friend in friends | orderBy:'+': true track by $index"
Vibhum Bhardwaj

125

Przepraszam, że o tym wspomniałem po roku, ale jest nowe, łatwiejsze rozwiązanie , które działa dla Angulara v1.3.0-rc.5 i nowszych .

Jest wspomniany w dokumentach : „Jeśli nie podano żadnej właściwości (np.„ + ”), Wówczas do porównania miejsca sortowania używany jest sam element tablicy”. Tak więc rozwiązaniem będzie:

ng-repeat="friend in friends | orderBy:'-'" lub

ng-repeat="friend in friends | orderBy:'+':true"

To rozwiązanie wydaje się lepsze, ponieważ nie modyfikuje tablicy i nie wymaga dodatkowych zasobów obliczeniowych (przynajmniej w naszym kodzie). Przeczytałem wszystkie istniejące odpowiedzi i nadal wolę tę od nich.


1
Dzięki za wskazówkę! Jako jeden do góry każdy, kto to czyta, wygląda na to, że nie działa w rc4 ( v1.3.0-rc.4). Jeśli ktoś ma szansę wypróbować go w nowej wersji, daj nam znać!
mikermcneil

1
@mikermcneil Dzięki za komentarz! Zgodnie z tą samą dokumentacją powinno działać od v1.3.0-rc.5( rc.5 docs vs rc.4 docs ). Zaktualizowałem odpowiedź
Dmitry Gonchar

1
Nie działa dla mnie (v1.3.5). Próbowaliśmy orderBy:'+':true, orderBy:'-':true, orderBy:'-':false, orderBy:'+':false:(
Cody

2
@Cody Przepraszamy za późną odpowiedź. Proszę bardzo - działający przykład z kątowym v1.3.5 jsfiddle.net/dmitry_gonchar/L98foxhm/1 . Prawdopodobnie problem był w innym miejscu.
Dmitry Gonchar

1
@alevkon Prawda. Ale działa, jeśli podasz pole („+ id”, „-id” fe). Może to jest błąd w Angular, że nie działa z normalną kolejnością, jeśli nie określisz pola? Wziąłem tę metodę z dokumentacji (link znajduje się w odpowiedzi), więc byłem zaskoczony tak samo jak ty. W każdym razie pytanie dotyczyło sposobu odwrócenia tablicy.
Dmitry Gonchar

54

Możesz odwrócić za pomocą parametru $ index

<tr ng-repeat="friend in friends | orderBy:'$index':true">

13
Powinien działać, ale nie działa (próbował z cytatami i bez nich $index). Jestem na Angular 1.1.5.
Inżynier

2
Pracowałem dla mnie (korzystałem z właściwości do sortowania zamiast indeksu $) stackoverflow.com/questions/16261348/…
Certs

4
Nie działa z AngularJS 1.2.13. Zmodyfikowałem moją tablicę obiektów, aby dodać identyfikator do każdego obiektu. Identyfikator będący indeksem obiektu wewnątrz tablicy. Potem ng-repeat="friend in friends | orderBy:'id':true"działa.
tanguy_k

51

Proste rozwiązanie: - (nie trzeba wykonywać żadnych metod)

ng-repeat = "friend in friends | orderBy: reverse:true"

2
Działa dobrze dla mnie. Dzięki!
HankScorpio

17

Możesz po prostu wywołać metodę w swoim zasięgu, aby ją odwrócić, na przykład:

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.0.5/angular.min.js"></script>
    <script>
    angular.module('myApp', []).controller('Ctrl', function($scope) {
        $scope.items = [1, 2, 3, 4];
        $scope.reverse = function(array) {
            var copy = [].concat(array);
            return copy.reverse();
        }
    });
    </script>
</head>
<body ng-controller="Ctrl">
    <ul>
        <li ng-repeat="item in items">{{item}}</li>
    </ul>
    <ul>
        <li ng-repeat="item in reverse(items)">{{item}}</li>
    </ul>
</body>
</html>

Zauważ, że $scope.reversetworzy kopię tablicy, ponieważ Array.prototype.reversemodyfikuje oryginalną tablicę.


13

jeśli używasz 1.3.x, możesz użyć następujących

{{ orderBy_expression | orderBy : expression : reverse}}

Przykład Lista książek według daty publikacji w kolejności malejącej

<div ng-repeat="book in books|orderBy:'publishedDate':true">

źródło: https://docs.angularjs.org/api/ng/filter/orderBy


11

Jeśli używasz angularjs w wersji 1.4.4 i nowszej , łatwym sposobem sortowania jest użycie „ $ index ”.

 <ul>
  <li ng-repeat="friend in friends|orderBy:$index:true">{{friend.name}}</li>
</ul>

zobacz demo


1

Korzystając z MVC w .NET z Angularem, zawsze możesz użyć OrderByDecending () podczas wykonywania zapytania db w następujący sposób:

var reversedList = dbContext.GetAll().OrderByDecending(x => x.Id).ToList();

Następnie po stronie Angulara zostanie już odwrócony w niektórych przeglądarkach (IE). W przypadku obsługi Chrome i FF należy dodać zamówienie:

<tr ng-repeat="item in items | orderBy:'-Id'">

W tym przykładzie sortowałbyś w kolejności malejącej według właściwości .Id. Jeśli używasz stronicowania, staje się to bardziej skomplikowane, ponieważ sortowana byłaby tylko pierwsza strona. Trzeba by to obsłużyć za pomocą pliku filtru .js dla kontrolera lub w inny sposób.


0

Możesz także użyć .reverse (). Jest to natywna funkcja tablicowa

<div ng-repeat="friend in friends.reverse()">{{friend.name}}</div>


Twój głos w dół może oznaczać tylko jedno: masz więcej przychodzących danych. Jeśli {} lub [] nadal będą odbierać dane, oczywiście będą one cofane za każdym razem. To nowy skrót
Pian0_M4n

Ostrzeżenie dla każdego, kto chce tego użyć: reverseodwraca tablicę na miejscu, nie tylko zwraca odwróconą kopię. Oznacza to, że za każdym razem, gdy jest to oceniane, tablica będzie odwracana.
jcaron,

0

To dlatego, że używasz obiektu JSON. Gdy napotkasz takie problemy, zmień swój obiekt JSON na obiekt JSON Array.

Na przykład,

{"India":"IN","America":"US","United Kingdon":"UK"} json object
[{"country":"India","countryId":"IN"},{"country":"America","countryId":"US"},{"country":"United Kingdon","countryId":"UK"}] 


0

Znalazłem coś takiego, ale zamiast tablicy używam obiektów.

Oto moje rozwiązanie dla obiektów:

Dodaj niestandardowy filtr:

app.filter('orderObjectBy', function() {
    return function(items, field, reverse){

        var strRef = function (object, reference) {
            function arr_deref(o, ref, i) {
                return !ref ? o : (o[ref.slice(0, i ? -1 : ref.length)]);
            }
            function dot_deref(o, ref) {
                return !ref ? o : ref.split('[').reduce(arr_deref, o);
            }
            return reference.split('.').reduce(dot_deref, object);
        };

        var filtered = [];

        angular.forEach(items, function(item) {
           filtered.push(item);
        });
        filtered.sort(function (a, b) {
           return (strRef(a, field) > strRef(a, field) ? 1 : -1);
        });
        if(reverse) filtered.reverse();
        return filtered;
    };
});

Które można następnie wykorzystać jak

<div ng-repeat="(key, value) in items | orderObjectBy:'field.any.deep':true">

Jeśli potrzebujesz obsługi starej przeglądarki, musisz zdefiniować funkcję zmniejszania (jest dostępna tylko w ECMA-262 mozilla.org )

// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
if (!Array.prototype.reduce) {
Array.prototype.reduce = function(callback /*, initialValue*/) {
'use strict';
  if (this == null) {
    throw new TypeError('Array.prototype.reduce called on null or undefined');
  }
  if (typeof callback !== 'function') {
    throw new TypeError(callback + ' is not a function');
  }
  var t = Object(this), len = t.length >>> 0, k = 0, value;
  if (arguments.length == 2) {
    value = arguments[1];
  } else {
    while (k < len && !(k in t)) {
      k++; 
    }
    if (k >= len) {
      throw new TypeError('Reduce of empty array with no initial value');
    }
    value = t[k++];
  }
  for (; k < len; k++) {
    if (k in t) {
      value = callback(value, t[k], k, t);
    }
  }
  return value;
};
}

0

Sam byłem sfrustrowany tym problemem, dlatego zmodyfikowałem filtr utworzony przez @Trevor Senior, gdy miałem problem z konsolą, mówiąc, że nie można użyć metody odwrotnej. Ja również chciałem zachować integralność obiektu, ponieważ to właśnie Angular pierwotnie używa w dyrektywie powtarzania ng. W tym przypadku użyłem danych wejściowych głupek (klawisz), ponieważ konsola się zdenerwuje, mówiąc, że są duplikaty, aw moim przypadku muszę śledzić według $ index.

Filtr:

angular.module('main').filter('reverse', function() {
    return function(stupid, items) {
    var itemss = items.files;
    itemss = itemss.reverse();  
    return items.files = itemss; 
  };
});

HTML: <div ng-repeat="items in items track by $index | reverse: items">


0

Dodam jedną odpowiedź, o której nikt nie wspomniał. Spróbowałbym zmusić serwer do zrobienia tego, jeśli taki masz. Filtrowanie po stronie klienta może być niebezpieczne, jeśli serwer zwróci wiele rekordów. Ponieważ możesz zostać zmuszony do dodania stronicowania. Jeśli masz stronicowanie z serwera, filtr klienta na zamówienie, będzie na bieżącej stronie. Co wprowadzałoby użytkownika w błąd. Jeśli więc masz serwer, wyślij zamówienie wraz z połączeniem i pozwól, aby serwer je zwrócił.


0

Przydatna wskazówka:

Możesz odwrócić swoją tablicę za pomocą waniliowej Js: twoja tablica .reverse ()

Uwaga: odwrócenie jest destrukcyjne, więc zmieni tablicę, a nie tylko zmienną.


-2

Sugerowałbym, że użycie natywnej metody odwrotnej do tablicy jest zawsze lepszym wyborem niż tworzenie filtra lub używanie $index.

<div ng-repeat="friend in friends.reverse()">{{friend.name}}</div>

Plnkr_demo .


Cofasz pierwotną tablicę ... Lepszym rozwiązaniem byłoby zwrócenie nowej tablicy, która jest odwrócona.
Vandervidi
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.