Par plusieurs champs en angulaire

382

Comment trier en utilisant plusieurs champs en même temps en angulaire? poing par groupe puis par sous-groupe pour l'exemple

$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}];

Je voulais afficher cela comme

groupe: Sous-groupe

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'" />
gmeka
la source

Réponses:

659

Veuillez voir ceci:

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

<div ng-repeat="division in divisions | orderBy:['group','sub']">{{division.group}}-{{division.sub}}</div>
Garçon grassouillet
la source
137
orderBy:['-group','sub']pour trier par groupordre inverse.
Dmitriy
1
Le champ de groupe est-il prioritaire pour être le premier dans la liste orderBy?
luchosrock
5
@luchosrock, oui, comme prévu. Jouer avec le jsfiddle fourni confirme facilement que la priorité de tri est de gauche à droite pour les champs de tri fournis.
Patrick Refondini
2
Notez que le paramètre optionnel reverseOrder ne prend pas en charge un tableau comme le fait l'expression param, mais vous pouvez l'omettre et fournir à la place un ordre de tri sur chaque élément du tableau afin qu'ils soient inversés (ou non) séparément. Exemple: orderBy: ['group', '-sub'] triera par groupe de façon normale, puis par sous dans l'ordre inverse. Il est possible d'obtenir des combinaisons complexes de cette façon.
Daniel Nalbach
1
Nous avons simulé la priorité dans notre boutique en donnant aux éléments du tableau une propriété booléenne, puis en l'utilisant comme première option. Exemple: orderBy: ['-featured', 'title'], qui a fait que les vrais éléments en vedette se trouvaient en haut (par ordre alphabétique), puis le reste des éléments répertoriés par ordre alphabétique.
Daniel Nalbach
47

Si vous souhaitez trier sur plusieurs champs à l'intérieur du contrôleur, utilisez ceci

$filter('orderBy')($scope.property_list, ['firstProp', 'secondProp']);

Voir aussi https://docs.angularjs.org/api/ng/filter/orderBy

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

Tableau d'utilisateurs au lieu de plusieurs commandes

Thambuleena
la source
5

Le tri peut être effectué en utilisant le filtre 'orderBy' en angulaire.

Deux façons: 1. De la vue 2. Du contrôleur

  1. De la vue

Syntaxe:

{{array | orderBy : expression : reverse}} 

Par exemple:

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

Syntaxe:

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

Par exemple:

$scope.filteredArray = $filter.orderBy($scope.users, ['name', 'age'], true);
Tessy Thomas
la source
5

Il y a 2 façons de faire des filtres AngularJs, une dans le HTML en utilisant {{}} et une dans les fichiers JS réels ...

Vous pouvez résoudre votre problème en utilisant:

{{ Expression | orderBy : expression : reverse}}

si vous l'utilisez dans le HTML ou utilisez quelque chose comme:

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

L'inverse est facultatif à la fin, il accepte un booléen et si c'est vrai, il inversera le tableau pour vous, très pratique pour inverser votre tableau ...

Alireza
la source
Aussi ici pour jeter un œil: docs.angularjs.org/api/ng/filter/orderBy
Alireza
0

J'ai écrit cette pièce pratique pour trier par plusieurs colonnes / propriétés d'un objet. À chaque clic de colonne successif, le code stocke la dernière colonne cliquée et l'ajoute à une liste croissante de noms de chaîne de colonne cliquée, en les plaçant dans un tableau appelé sortArray. Le filtre angulaire "orderBy" intégré lit simplement la liste sortArray et classe les colonnes selon l'ordre des noms de colonnes qui y sont stockés. Ainsi, le dernier nom de colonne cliqué devient le filtre ordonné principal, le précédent a cliqué sur le suivant en priorité, etc.

<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>
Stokely
la source
0

Pipe créée pour le tri. Accepte à la fois une chaîne et un tableau de chaînes, triés par plusieurs valeurs. Fonctionne pour Angular (pas AngularJS). Prend en charge le tri pour la chaîne et les nombres.

@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
            }
        });
    }
}
Andris
la source
1
PS: En fait, à mon avis, personne n'a actuellement répondu à la question réelle, car c'était pour Angular, pas AngularJS. Ma solution fonctionne à partir d'Angular 2. Testé sur Angular 7.2.15
Andris
Vous devriez considérer a) quand cette question a-t-elle été posée, et b) quand Angular 2 a-t-il été annoncé pour la première fois.
Nick
@andris Avez-vous un exemple de code de bout en bout fonctionnel hébergé quelque part?
pierre roulante
Désolé, mais non :(
Andris
-8

Assurez-vous que le tri n'est pas trop compliqué pour l'utilisateur final. J'ai toujours pensé que le tri par groupe et sous-groupe était un peu compliqué à comprendre. Si c'est un utilisateur technique final, cela peut être OK.

Jens Alenius
la source
Ce n'est même pas un "commentaire" pertinent. Certainement pas une réponse à la question
Afshin Moazami
Est-il si faux de vous demander si l'approche actuelle est la meilleure lorsque vous faites du développement d'interface graphique? L'expérience de l'utilisateur final me semble pertinente
Jens Alenius
Il existe de nombreux scénarios dans lesquels le tri par plusieurs propriétés facilite la compréhension de l'organisation par l'utilisateur. Vous regroupez essentiellement les choses en catégories.
Owen Johnson