Winkel ng-Wiederholung in umgekehrter Richtung


227

Wie kann ich ein umgekehrtes Array im Winkel erhalten? Ich versuche, den orderBy-Filter zu verwenden, aber zum Sortieren wird ein Prädikat (z. B. 'name') benötigt:

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

Gibt es eine Möglichkeit, das ursprüngliche Array umzukehren, ohne es zu sortieren? so wie das:

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

4
Dies ist der neue und richtige Weg stackoverflow.com/a/16261373/988830
om471987

@QuiteNothing Das ist der richtige Weg, wenn Sie ein Array mit einem Ausdruck umkehren möchten. In diesem Fall war die Frage, wie ein Array ohne eines verehrt werden kann.
JayQuerie.com

<tr ng-repeat = "Freund in Freunden | orderBy: '- name'">
desmati

Siehe meine Antwort unten für die einfache 1 Zeile und die richtige Lösung. Es sind keine Methoden erforderlich. Ich frage mich, warum die Leute dafür zusätzliche Methoden entwickeln.
Muhammad Hassam

Verwenden Sie immer Filter, um das ng-repeatVerhalten zu ändern ! @ Trevor Senior hat gute Arbeit geleistet.
Amir Savand

Antworten:


329

Ich würde vorschlagen, einen benutzerdefinierten Filter wie diesen zu verwenden:

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

Welches kann dann verwendet werden wie:

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

Sehen Sie, wie es hier funktioniert: Plunker-Demonstration


Dieser Filter kann nach Ihren Wünschen angepasst werden. Ich habe andere Beispiele in der Demonstration geliefert. Einige Optionen umfassen das Überprüfen, ob die Variable ein Array ist, bevor die Umkehrung durchgeführt wird, oder das mildere Umkehren, um das Umkehren von mehr Dingen wie Zeichenfolgen zu ermöglichen.


21
Nett! Beachten Sie jedoch, dass items.reverse()das Array geändert wird, anstatt nur ein neues zu erstellen und es zurückzugeben.
Anders Ekdahl

12
Vielen Dank! Ich hatte das übersehen. Ich warf ein slice(), um dieses Problem zu lösen.
JayQuerie.com

9
Sie sollten hinzufügen if (!angular.isArray(items)) return false;, um zu überprüfen, ob Sie ein Array haben, bevor Sie versuchen, es umzukehren.
Respektieren Sie den Code

6
Müssen Sie defensiver gegen Null sein, sollten Sie stattdessen Folgendes verwenden: Artikel zurückgeben? items.slice (). reverse (): [];
Chris Yeung

5
@ Chris Yeung: Es ist nicht ratsam, leer "[]" zurückzugeben, wenn null. Besser den ursprünglichen Wert zurückgeben.
Siva

202

Das habe ich benutzt:

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

Aktualisieren:

Meine Antwort war OK für die alte Version von Angular. Jetzt sollten Sie verwenden

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

oder

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

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


Uing track by, dies ist der einzige Weg, der für mich funktioniert hat

@ Delboud Sie sollten Track von nach Bestellung verwendenBy:ng-repeat="friend in friends | orderBy:'+': true track by $index"
Vibhum Bhardwaj

125

Es tut uns leid, dass Sie dies nach einem Jahr angesprochen haben , aber es gibt eine neue, einfachere Lösung , die für Angular v1.3.0-rc.5 und höher funktioniert .

In den Dokumenten wird erwähnt : "Wenn keine Eigenschaft angegeben ist (z. B. '+'), wird das Array-Element selbst verwendet, um zu vergleichen, wo sortiert wird." Die Lösung lautet also:

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

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

Diese Lösung scheint besser zu sein, da sie kein Array ändert und keine zusätzlichen Rechenressourcen erfordert (zumindest in unserem Code). Ich habe alle vorhandenen Antworten gelesen und bevorzuge diese immer noch.


1
Danke für den Tipp! Es sieht so aus, als würde dies in rc4 ( v1.3.0-rc.4) nicht funktionieren . Wenn jemand die Möglichkeit hat, es in der neuen Version zu versuchen, lassen Sie es uns wissen!
Mikermcneil

1
@mikermcneil Danke für den Kommentar! Nach der gleichen Dokumentation sollte es ab v1.3.0-rc.5( rc.5 docs vs rc.4 docs ) funktionieren . Ich habe die Antwort aktualisiert
Dmitry Gonchar

1
Funktioniert nicht für mich (v1.3.5). Versuchte orderBy:'+':true, orderBy:'-':true, orderBy:'-':false, orderBy:'+':false:(
Cody

2
@Cody Entschuldigung für die späte Antwort. Los geht's - ein Arbeitsbeispiel mit eckigem v1.3.5 jsfiddle.net/dmitry_gonchar/L98foxhm/1 . Wahrscheinlich war das Problem an einem anderen Ort.
Dmitry Gonchar

1
@alevkon Richtig. Aber es funktioniert, wenn Sie das Feld angeben ('+ id', '-id' fe). Vielleicht ist dies ein Fehler in Angular, dass es nicht mit normaler Reihenfolge funktioniert, wenn Sie kein Feld angeben? Ich habe diese Methode aus den Dokumenten genommen (Link ist in der Antwort), also war ich genauso überrascht wie Sie. Wie dem auch sei, war die Frage , wie man umgekehrt ein Array.
Dmitry Gonchar

54

Sie können mit dem Parameter $ index umkehren

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

13
Sollte funktionieren, funktioniert aber nicht (mit und ohne Anführungszeichen $index). Ich bin auf Angular 1.1.5.
Ingenieur

2
Arbeitete für mich (benutzte eine Eigenschaft zum Sortieren anstelle von $ index) stackoverflow.com/questions/16261348/…
Zertifikate

4
Funktioniert nicht mit AngularJS 1.2.13. Ich habe mein Objektarray geändert, um jedem Objekt eine ID hinzuzufügen. Die ID ist der Index des Objekts innerhalb des Arrays. Dann ng-repeat="friend in friends | orderBy:'id':true"funktioniert.
Tanguy_k

51

Einfache Lösung: - (keine Methoden erforderlich)

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

2
Funktioniert gut für mich. Vielen Dank!
HankScorpio

17

Sie können einfach eine Methode in Ihrem Bereich aufrufen, um sie für Sie umzukehren:

<!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>

Beachten Sie, dass das $scope.reverseeine Kopie des Arrays erstellt, da Array.prototype.reversedas ursprüngliche Array geändert wird.


13

Wenn Sie 1.3.x verwenden, können Sie Folgendes verwenden

{{ orderBy_expression | orderBy : expression : reverse}}

Beispiel Listet Bücher nach Veröffentlichungsdatum in absteigender Reihenfolge auf

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

Quelle: https://docs.angularjs.org/api/ng/filter/orderBy


11

Wenn Sie anglejs Version 1.4.4 und höher verwenden , können Sie den " $ index " auf einfache Weise sortieren .

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

Demo ansehen


1

Wenn Sie MVC in .NET mit Angular verwenden, können Sie OrderByDecending () immer verwenden, wenn Sie Ihre Datenbankabfrage wie folgt ausführen:

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

Auf der Winkelseite wird es dann in einigen Browsern (IE) bereits umgekehrt. Wenn Sie Chrome und FF unterstützen, müssen Sie orderBy hinzufügen:

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

In diesem Beispiel würden Sie in absteigender Reihenfolge nach der .Id-Eigenschaft sortieren. Wenn Sie Paging verwenden, wird dies komplizierter, da nur die erste Seite sortiert wird. Sie müssten dies über eine .js-Filterdatei für Ihren Controller oder auf andere Weise erledigen.


0

Sie können auch .reverse () verwenden. Es ist eine native Array-Funktion

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


Ihre Ablehnung kann nur eines bedeuten: Sie haben mehr eingehende Daten. Wenn das {} oder [] weiterhin Daten empfängt, wird es natürlich jedes Mal umgekehrt. Es ist eine neue Zusammenfassung
Pian0_M4n

Warnung für alle, die dies verwenden reversemöchten : Das Array wird umgekehrt, es wird nicht nur eine umgekehrte Kopie zurückgegeben. Dies bedeutet, dass jedes Mal, wenn dies ausgewertet wird, das Array umgekehrt wird.
JCaron

0

Dies liegt daran, dass Sie JSON Object verwenden. Wenn Sie auf solche Probleme stoßen, ändern Sie Ihr JSON-Objekt in JSON-Array-Objekt.

Beispielsweise,

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


0

Ich habe so etwas gefunden, aber anstelle von Array verwende ich Objekte.

Hier ist meine Lösung für Objekte:

Benutzerdefinierten Filter hinzufügen:

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

Welches kann dann wie verwendet werden

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

Wenn Sie Unterstützung für alte Browser benötigen, müssen Sie die Reduzierungsfunktion definieren (diese ist nur in ECMA-262 mozilla.org verfügbar ).

// 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

Ich war selbst frustriert über dieses Problem und habe den von @Trevor Senior erstellten Filter geändert, als ich auf ein Problem mit meiner Konsole stieß, das besagte, dass die umgekehrte Methode nicht verwendet werden konnte. Ich wollte auch die Integrität des Objekts beibehalten, da Angular dies ursprünglich in einer ng-repeat-Direktive verwendet. In diesem Fall habe ich die Eingabe von dumm (Schlüssel) verwendet, da sich die Konsole darüber aufregt, dass es Duplikate gibt, und in meinem Fall musste ich nach $ index verfolgen.

Filter:

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

Ich füge eine Antwort hinzu, die niemand erwähnt hat. Ich würde versuchen, den Server dazu zu bringen, wenn Sie einen haben. Die clientseitige Filterung kann gefährlich sein, wenn der Server viele Datensätze zurückgibt. Weil Sie möglicherweise gezwungen sind, Paging hinzuzufügen. Wenn Sie Paging vom Server haben, befindet sich der bestellte Clientfilter auf der aktuellen Seite. Das würde den Endbenutzer verwirren. Wenn Sie also einen Server haben, senden Sie den Auftrag mit dem Anruf und lassen Sie ihn vom Server zurückgeben.


0

Nützlicher Tipp:

Sie können Ihr Array mit Vanilla Js umkehren: yourarray .reverse ()

Achtung: Die Umkehrung ist destruktiv, daher ändert sich Ihr Array, nicht nur die Variable.


-2

Ich würde vorschlagen, dass die Verwendung der nativen Array-Umkehrmethode immer die bessere Wahl ist, als Filter zu erstellen oder zu verwenden $index.

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

Plnkr_demo .


Sie kehren das ursprüngliche Array um ... Eine bessere Vorgehensweise wäre, ein neues Array zurückzugeben, das umgekehrt ist.
Vandervidi
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.