orderBy mehrere Felder in Angular


382

Wie sortiere ich, indem ich mehrere Felder gleichzeitig im Winkel verwende? Faust nach Gruppe und dann nach Untergruppe zum Beispiel

$scope.divisions = [{'group':1,'sub':1}, {'group':2,'sub':10}, {'group':1,'sub':2},{'group':1,'sub':20},{'group':2,'sub':1},
    {'group':2,'sub':11}];

Ich wollte dies als anzeigen

Gruppe: Untergruppe

1 - 1

1 - 2

1 - 20

2 - 1

2 - 10

2 - 11

<select ng-model="divs" ng-options="(d.group+' - '+d.sub) for d in divisions | orderBy:'group' | orderBy:'sub'" />

Antworten:


659

Bitte sehen Sie dies:

http://jsfiddle.net/JSWorld/Hp4W7/32/

<div ng-repeat="division in divisions | orderBy:['group','sub']">{{division.group}}-{{division.sub}}</div>

137
orderBy:['-group','sub']zum Sortieren groupin umgekehrter Reihenfolge.
Dmitriy

1
Hat das Gruppenfeld Priorität, um in der orderBy-Liste an erster Stelle zu stehen?
Luchosrock

5
@ Luchosrock, ja, wie erwartet. Das Spielen mit der bereitgestellten jsfiddle bestätigt leicht, dass die Sortierpriorität für die bereitgestellten Sortierfelder von links nach rechts ist.
Patrick Refondini

2
Beachten Sie, dass der optionale Parameter reverseOrder ein Array nicht wie der Ausdrucksparameter unterstützt. Sie können ihn jedoch weglassen und stattdessen die Sortierreihenfolge für jedes Arrayelement angeben, damit sie separat umgekehrt werden (oder nicht). Beispiel: orderBy: ['group', '-sub'] sortiert auf normale Weise nach Gruppen und dann in umgekehrter Reihenfolge nach Sub. Auf diese Weise können einige komplexe Kombinationen erhalten werden.
Daniel Nalbach

1
Wir haben die Priorität in unserem Shop simuliert, indem wir den Array-Elementen eine boolesche Eigenschaft gegeben und diese dann als erste Option verwendet haben. Beispiel: orderBy: ['-featured', 'title'], wodurch die vorgestellten wahren Elemente oben (alphabetisch) und die übrigen Elemente alphabetisch aufgelistet wurden.
Daniel Nalbach


21
<select ng-model="divs" ng-options="(d.group+' - '+d.sub) for d in divisions | orderBy:['group','sub']" />

Benutzerarray statt mehrfacher orderBY


5

Die Sortierung kann mithilfe des Filters 'orderBy' im Winkel erfolgen.

Zwei Möglichkeiten: 1. Aus der Ansicht 2. Aus der Steuerung

  1. Aus der Sicht

Syntax:

{{array | orderBy : expression : reverse}} 

Zum Beispiel:

 <div ng-repeat="user in users | orderBy : ['name', 'age'] : true">{{user.name}}</div>
  1. Vom Controller

Syntax:

$filter.orderBy(array, expression, reverse);

Zum Beispiel:

$scope.filteredArray = $filter.orderBy($scope.users, ['name', 'age'], true);

5

Es gibt zwei Möglichkeiten, AngularJs-Filter auszuführen, eine im HTML-Code mit {{}} und eine in tatsächlichen JS-Dateien ...

Sie können Ihr Problem lösen, indem Sie:

{{ Expression | orderBy : expression : reverse}}

Wenn Sie es im HTML verwenden oder etwas wie:

$filter('orderBy')(yourArray, yourExpression, reverse)

Die Umkehrung ist am Ende optional, sie akzeptiert einen Booleschen Wert und wenn dies zutrifft, wird das Array für Sie umgekehrt, eine sehr praktische Möglichkeit, Ihr Array umzukehren ...


Auch hier, um einen Blick darauf zu werfen: docs.angularjs.org/api/ng/filter/orderBy
Alireza

0

Ich habe dieses praktische Stück geschrieben, um nach mehreren Spalten / Eigenschaften eines Objekts zu sortieren. Bei jedem aufeinanderfolgenden Spaltenklick speichert der Code die zuletzt angeklickte Spalte und fügt sie einer wachsenden Liste angeklickter Spaltenzeichenfolgennamen hinzu, wobei sie in einem Array namens sortArray platziert werden. Der integrierte Angular-Filter "orderBy" liest einfach die sortArray-Liste und ordnet die Spalten in der Reihenfolge der dort gespeicherten Spaltennamen. Der Name der zuletzt angeklickten Spalte wird also zum primär geordneten Filter, der vorherige zum vorrangigen Filter usw. Die umgekehrte Reihenfolge wirkt sich auf alle Spaltenreihenfolgen gleichzeitig aus und schaltet für den vollständigen Array-Listensatz aufsteigend / absteigend um:

<script>
    app.controller('myCtrl', function ($scope) {
        $scope.sortArray = ['name'];
        $scope.sortReverse1 = false;
        $scope.searchProperty1 = '';
        $scope.addSort = function (x) {
            if ($scope.sortArray.indexOf(x) === -1) {
                $scope.sortArray.splice(0,0,x);//add to front
            }
            else {
                $scope.sortArray.splice($scope.sortArray.indexOf(x), 1, x);//remove
                $scope.sortArray.splice(0, 0, x);//add to front again
            }
        };
        $scope.sushi = [
        { name: 'Cali Roll', fish: 'Crab', tastiness: 2 },
        { name: 'Philly', fish: 'Tuna', tastiness: 2 },
        { name: 'Tiger', fish: 'Eel', tastiness: 7 },
        { name: 'Rainbow', fish: 'Variety', tastiness: 6 },
        { name: 'Salmon', fish: 'Misc', tastiness: 2 }
        ];
    });
</script>
<table style="border: 2px solid #000;">
<thead>
    <tr>
        <td><a href="#" ng-click="addSort('name');sortReverse1=!sortReverse1">NAME<span ng-show="sortReverse1==false">&#9660;</span><span ng-show="sortReverse1==true">&#9650;</span></a></td>
        <td><a href="#" ng-click="addSort('fish');sortReverse1=!sortReverse1">FISH<span ng-show="sortReverse1==false">&#9660;</span><span ng-show="sortReverse1==true">&#9650;</span></a></td>
        <td><a href="#" ng-click="addSort('tastiness');sortReverse1=!sortReverse1">TASTINESS<span ng-show="sortReverse1==false">&#9660;</span><span ng-show="sortReverse1==true">&#9650;</span></a></td>
    </tr>
</thead>
<tbody>
    <tr ng-repeat="s in sushi | orderBy:sortArray:sortReverse1 | filter:searchProperty1">
        <td>{{ s.name }}</td>
        <td>{{ s.fish }}</td>
        <td>{{ s.tastiness }}</td>
    </tr>
</tbody>
</table>

0

Pipe zum Sortieren erstellt. Akzeptiert sowohl Zeichenfolgen als auch Array von Zeichenfolgen und sortiert nach mehreren Werten. Funktioniert für Angular (nicht AngularJS). Unterstützt sowohl das Sortieren nach Zeichenfolgen als auch nach Zahlen.

@Pipe({name: 'orderBy'})
export class OrderBy implements PipeTransform {
    transform(array: any[], filter: any): any[] {
        if(typeof filter === 'string') {
            return this.sortAray(array, filter)
        } else {
            for (var i = filter.length -1; i >= 0; i--) {
                array = this.sortAray(array, filter[i]);
            }

            return array;
        }
    }

    private sortAray(array, field) {
        return array.sort((a, b) => {
            if(typeof a[field] !== 'string') {
                a[field] !== b[field] ? a[field] < b[field] ? -1 : 1 : 0
            } else {
                a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0
            }
        });
    }
}

1
PS: Meiner Meinung nach hat derzeit niemand die eigentliche Frage beantwortet, weil es sich um Angular handelte, nicht um AngularJS. Meine Lösung funktioniert ab Angular 2. Getestet auf Angular 7.2.15
Andris

Sie sollten überlegen, a) wann diese Frage gestellt wurde und b) wann Angular 2 zum ersten Mal angekündigt wurde.
Nick

@andris Haben Sie ein funktionierendes End-to-End-Codebeispiel, das irgendwo gehostet wird?
Rolling Stone

Sorry, aber nein :(
Andris

-8

Stellen Sie sicher, dass die Sortierung für den Endbenutzer nicht zu kompliziert ist. Ich habe immer gedacht, dass das Sortieren nach Gruppen und Untergruppen etwas kompliziert zu verstehen ist. Wenn es sich um einen technischen Endbenutzer handelt, ist dies möglicherweise in Ordnung.


Dies ist nicht einmal ein relevanter "Kommentar". Sicher keine Antwort auf die Frage
Afshin Moazami

Ist es so falsch, sich zu fragen, ob der aktuelle Ansatz der beste ist, wenn Sie eine GUI-Entwicklung durchführen? Die Endbenutzererfahrung fühlt sich für mich relevant an
Jens Alenius

Es gibt viele Szenarien, in denen das Sortieren nach mehreren Eigenschaften dem Benutzer das Verständnis der Organisation erleichtert. Sie gruppieren Dinge im Wesentlichen in Kategorien.
Owen Johnson
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.