orderBy vários campos em Angular

382

Como classificar usando vários campos ao mesmo tempo em angular? punho por grupo e depois por subgrupo, por exemplo

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

Eu queria exibir isso como

grupo: Subgrupo

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
fonte

Respostas:

659

Por favor, veja isto:

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

<div ng-repeat="division in divisions | orderBy:['group','sub']">{{division.group}}-{{division.sub}}</div>
Menino gordinho
fonte
137
orderBy:['-group','sub']para classificar por groupordem inversa.
Dmitriy
11
O campo do grupo tem prioridade por ser o primeiro na lista orderBy?
Luchosrock 01/12/14
5
@luchosrock, sim, como esperado. Jogar com o jsfiddle fornecido facilmente confirma a prioridade da classificação da esquerda para a direita nos campos de classificação fornecidos.
Patrick Refondini
2
Observe que o parâmetro opcional reverseOrder não suporta uma matriz como a expressão param, mas você pode omiti-lo e, em vez disso, fornecer ordem de classificação em cada item da matriz para que sejam revertidos (ou não) separadamente. Exemplo: orderBy: ['group', '-sub'] classificará por grupo da maneira normal e depois por sub na ordem inversa. É possível obter algumas combinações complexas dessa maneira.
Daniel Nalbach
11
Simulamos a prioridade em nossa loja, fornecendo aos itens da matriz uma propriedade booleana e, em seguida, usando-a como primeira opção. Exemplo: orderBy: ['-featured', 'title'], que fazia com que os itens verdadeiros em destaque estivessem na parte superior (em ordem alfabética) e depois no restante dos itens listados em ordem alfabética.
Daniel Nalbach
47

Se você deseja classificar em vários campos dentro do controlador, use este

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

Veja também https://docs.angularjs.org/api/ng/filter/orderBy

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

Matriz de usuário em vez de vários pedidos

Thambuleena
fonte
5

A classificação pode ser feita usando o filtro 'orderBy' em ângulo.

Duas maneiras: 1. Da vista 2. Do controlador

  1. Da vista

Sintaxe:

{{array | orderBy : expression : reverse}} 

Por exemplo:

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

Sintaxe:

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

Por exemplo:

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

Existem 2 maneiras de fazer filtros AngularJs, um no HTML usando {{}} e outro nos arquivos JS reais ...

Você pode resolver seu problema usando:

{{ Expression | orderBy : expression : reverse}}

se você usá-lo no HTML ou usar algo como:

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

O inverso é opcional no final, aceita um valor booleano e, se for verdade, reverterá a matriz para você, uma maneira muito útil de reverter sua matriz ...

Alireza
fonte
Também aqui para dar uma olhada: docs.angularjs.org/api/ng/filter/orderBy
Alireza
0

Eu escrevi esta peça útil para classificar por várias colunas / propriedades de um objeto. Com cada clique sucessivo na coluna, o código armazena a última coluna clicada e a adiciona a uma lista crescente de nomes de cadeias de caracteres clicadas, colocando-os em uma matriz chamada sortArray. O filtro Angular "orderBy" interno simplesmente lê a lista sortArray e ordena as colunas pela ordem dos nomes das colunas armazenadas nela. Portanto, o último nome da coluna clicada se torna o filtro ordenado primário, o anterior clicou no seguinte em precedência, 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
fonte
0

Pipe criado para classificação. Aceita sequência e matriz de sequências, classificando por vários valores. Funciona para Angular (não AngularJS). Suporta classificação de seqüência e números.

@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
fonte
11
PS: Na verdade, na minha opinião, atualmente ninguém respondeu a uma pergunta real, porque era para Angular, não para AngularJS. Minha solução funciona a partir angular 2. Testado em Angular 7.2.15
Andris
Você deve considerar a) quando essa pergunta foi feita eb) quando o Angular 2 foi anunciado pela primeira vez.
Nick
@andris Você tem um exemplo de código completo, de ponta a ponta, hospedado em algum lugar?
rolling stone
Desculpe, mas não :(
Andris
-8

Verifique se a classificação não é muito complicada para o usuário final. Eu sempre pensei que classificar grupos e subgrupos é um pouco complicado de entender. Se for um usuário final técnico, pode estar OK.

Jens Alenius
fonte
Este nem é um "comentário" relevante. Com certeza não é uma resposta para a pergunta
Afshin Moazami
É tão errado se perguntar se a abordagem atual é a melhor para o desenvolvimento de GUI? A experiência do usuário final se sente relevante para mim
Jens Alenius
Existem muitos cenários em que a classificação por várias propriedades facilita o entendimento da organização pelo usuário. Você está basicamente agrupando as coisas em categorias.
Owen Johnson