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>
Delremm
quelle
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.

JayQuerie.com
quelle
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

amit bakle
quelle
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.

Dmitry Gonchar
quelle
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">
jjhrms
quelle
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"
Muhammad Hassam
quelle
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.

Anders Ekdahl
quelle
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

Kumar
quelle
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

vishnu
quelle
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.

Whyoz
quelle
0

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

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

Pian0_M4n
quelle
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"}] 
user5891403
quelle
0

Der orderByFilter führt ab Winkel 1.4.5 eine stabile Sortierung durch. (Siehe die GitHub-Pull-Anfrage https://github.com/angular/angular.js/pull/12408 .)

Es reicht also aus, ein konstantes Prädikat zu verwenden und reverseFolgendes festzulegen true:

<div ng-repeat="friend in friends | orderBy:0:true">{{friend.name}}</div>
user1012976
quelle
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;
};
}
Twois
quelle
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">

Codierter Container
quelle
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.

Jens Alenius
quelle
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.

Ke Vin
quelle
-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 .

Vishnudas Tekale Kulkarni
quelle
Sie kehren das ursprüngliche Array um ... Eine bessere Vorgehensweise wäre, ein neues Array zurückzugeben, das umgekehrt ist.
Vandervidi