orden Por múltiples campos en Angular


382

¿Cómo ordenar usando múltiples campos al mismo tiempo en angular? puño por grupo y luego por subgrupo por ejemplo

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

Quería mostrar esto 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'" />

Respuestas:


659

Por favor vea esto:

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

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

137
orderBy:['-group','sub']para ordenar groupen orden inverso.
Dmitriy

1
¿El campo de grupo tiene prioridad para ser el primero en el orden Por lista?
luchosrock

55
@luchosrock, sí, como se esperaba. Jugar con el jsfiddle proporcionado confirma fácilmente que la prioridad de clasificación es de izquierda a derecha para los campos de clasificación proporcionados.
Patrick Refondini

2
Tenga en cuenta que el parámetro reverseOrder opcional no admite una matriz como lo hace la expresión param, pero puede omitirla y, en su lugar, proporcionar un orden de clasificación en cada elemento de la matriz para que se inviertan (o no) por separado. Ejemplo: orderBy: ['group', '-sub'] se ordenará por grupo de manera normal, luego por sub en orden inverso. Es posible obtener algunas combinaciones complejas de esta manera.
Daniel Nalbach

1
Simulamos prioridad en nuestra tienda dándole a los artículos de la matriz una propiedad booleana, y luego usándola como la primera opción. Ejemplo: orderBy: ['-featured', 'title'], que causó que los elementos verdaderos mostrados estuvieran en la parte superior (alfabéticamente), luego el resto de los elementos enumerados alfabéticamente.
Daniel Nalbach


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

Conjunto de usuarios en lugar de múltiples pedidos


5

La clasificación se puede hacer usando el filtro 'orderBy' en angular.

Dos formas: 1. Desde la vista 2. Desde el controlador

  1. De la vista

Sintaxis:

{{array | orderBy : expression : reverse}} 

Por ejemplo:

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

Sintaxis:

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

Por ejemplo:

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

5

Hay 2 formas de hacer filtros AngularJs, una en HTML usando {{}} y otra en archivos JS reales ...

Puede resolver su problema utilizando:

{{ Expression | orderBy : expression : reverse}}

si lo usa en HTML o usa algo como:

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

El reverso es opcional al final, acepta un valor booleano y, si es cierto, revertirá la matriz por usted, una forma muy práctica de revertir su matriz ...


También aquí para echar un vistazo: docs.angularjs.org/api/ng/filter/orderBy
Alireza

0

Escribí esta práctica pieza para ordenar por múltiples columnas / propiedades de un objeto. Con cada clic sucesivo en la columna, el código almacena la última columna en la que se hizo clic y la agrega a una lista creciente de nombres de cadenas de columnas en las que se hace clic, colocándolos en una matriz llamada sortArray. El filtro angular incorporado "orderBy" simplemente lee la lista sortArray y ordena las columnas por el orden de los nombres de las columnas almacenadas allí. Por lo tanto, el nombre de la última columna en la que se hizo clic se convierte en el filtro ordenado primario, el anterior hizo clic en el siguiente en precedencia, etc. El orden inverso afecta el orden de todas las columnas a la vez y alterna ascendente / descendente para el conjunto completo de la lista de matriz:

<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

Tubo creado para la clasificación. Acepta cadenas y series de cadenas, ordenando por múltiples valores. Funciona para Angular (no AngularJS). Soporta tanto la clasificación de cadenas como los 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
            }
        });
    }
}

1
PD: En realidad, en mi opinión, nadie ha respondido a la pregunta real, porque fue para Angular, no para AngularJS. Mi solución funciona a partir de Angular 2. Probado en Angular 7.2.15
Andris

Debería considerar a) cuándo se hizo esta pregunta, yb) cuándo se anunció por primera vez Angular 2.
Nick

@andris ¿Tiene un código de ejemplo de extremo a extremo funcionando alojado en algún lugar?
Rolling Stone

Lo sentimos, pero no :(
Andris

-8

Asegúrese de que la clasificación no sea demasiado complicada para el usuario final. Siempre pensé que ordenar por grupo y subgrupo es un poco complicado de entender. Si es un usuario final técnico, puede estar bien.


Esto ni siquiera es un "comentario" relevante. Seguro que no es una respuesta a la pregunta
Afshin Moazami

¿Es tan incorrecto preguntarse si el enfoque actual es el mejor cuando se hace el desarrollo de GUI? La experiencia del usuario final me parece relevante
Jens Alenius

Hay muchos escenarios en los que la clasificación por varias propiedades facilita al usuario la comprensión de la organización. Básicamente, estás agrupando las cosas en categorías.
Owen Johnson
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.