javascript - reorder - Ordenar una matriz de objetos en Angular2
sort array javascript by key (6)
Tengo problemas con la ordenación de una matriz de objetos en Angular2.
El objeto se parece a:
[
{
"name": "t10",
"ts": 1476778297100,
"value": "32.339264",
"xid": "DP_049908"
},
{
"name": "t17",
"ts": 1476778341100,
"value": "true",
"xid": "DP_693259"
},
{
"name": "t16",
"ts": 1476778341100,
"value": "true",
"xid": "DP_891890"
}
]
Y se está almacenando dentro de la variable de values
.
Todo lo que quiero es hacer que el bucle *ngFor
ordene por la propiedad name
.
<table *ngIf="values.length">
<tr *ngFor="let elem of values">
<td>{{ elem.name }}</td>
<td>{{ elem.ts }}</td>
<td>{{ elem.value }}</td>
</tr>
</table>
Intenté hacerlo con tuberías, pero fracasó miserablemente. Cualquier ayuda apreciada.
Enlace de Plunker : https://plnkr.co/edit/e9laTBnqJKb8VzhHEBmn?p=preview
Editar
Mi pipa
import {Component, Inject, OnInit, Pipe, PipeTransform} from ''@angular/core'';
@Component({
selector: ''watchlist'',
templateUrl: ''./watchlist.component.html'',
styleUrls: [''./watchlist.component.css''],
pipes: [ ArraySortPipe ]
})
@Pipe({
name: "sort"
})
export class ArraySortPipe implements PipeTransform {
transform(array: Array<string>, args: string): Array<string> {
array.sort((a: any, b: any) => {
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
return array;
}
}
Y simplemente ponga el nombre de la pipe
en el archivo html:
<tr *ngFor="let elem of values | sort">
Angular aún aconseja no usar tuberías para clasificar y filtrar, como en los angulares.
Ralentizará su aplicación, tendrá algunos problemas de rendimiento. Es mucho mejor proporcionar su clasificación en su componente antes de pasarlo a la plantilla.
El motivo se explica en https://angular.io/guide/pipes#no-filter-pipe
Si trabajas con un buen diseño de componentes estructurado, puedes hacerlo incluso en te setter:
@Input()
set users(users: Array<User>) {
this.usersResult = (users || []).sort((a: User, b: User) => a.name < b.name ? -1 : 1)
}
Aunque puede resolver este problema con una tubería, debe preguntarse si la reutilización de una tubería le es útil en su proyecto particular. ¿Necesitará a menudo ordenar los objetos por la clave de "nombre" en otros arreglos u otros componentes en el futuro? ¿Cambiarán estos datos con la frecuencia suficiente y de manera que resulte difícil clasificar el componente? ¿Necesitará la matriz ordenada en cualquier cambio en la vista o entradas?
Creé un plunker editado en el que la matriz está ordenada en el constructor del componente, pero no hay razón para que esta funcionalidad no pueda moverse a su propio método (por ejemplo, sortValuesArray) para reutilizarla si es necesario.
constructor() {
this.values.sort((a, b) => {
if (a.name < b.name) return -1;
else if (a.name > b.name) return 1;
else return 0;
});
}
Esto es adaptable a cualquiera de estos casos de uso.
import { Pipe, PipeTransform } from ''@angular/core'';
@Pipe({
name: ''sortBy''
})
export class SortByPipe implements PipeTransform {
transform(arr: Array<any>, prop: any, reverse: boolean = false): any {
if (arr === undefined) return
const m = reverse ? -1 : 1
return arr.sort((a: any, b: any): number => {
const x = a[prop]
const y = b[prop]
return (x === y) ? 0 : (x < y) ? -1*m : 1*m
})
}
}
Uso:-
<div *ngFor="let item of list | sortBy: ''isDir'': true">
ACTUALIZAR
Consulte Bo''s respuesta Bo''s ya que no se recomienda filtrar y clasificar las tuberías.
Prueba esto
Ordenar desde A hasta final de alpahbet:
this.suppliers.sort((a,b)=>a.SupplierName.localeCompare(b.SupplierName));
Z => A (orden inverso)
this.suppliers.sort((a,b)=>b.SupplierName.localeCompare(a.SupplierName));
Tu tubería espera cadenas pero obtiene objetos, debes adaptarla:
export class ArraySortPipe implements PipeTransform {
transform(array: Array<any>): Array<string> {
array.sort((a: any, b: any) => {
if (a.name < b.name) {
return -1;
} else if (a.name > b.name) {
return 1;
} else {
return 0;
}
});
return array;
}
}
es simple, por ejemplo, si tiene este objeto de matriz:
cars = ["Dodge", "Fiat", "Audi", "Volvo", "BMW", "Ford"];
y desea tener el objeto ordenado en el frente de HTML, use:
<li ng-repeat="x in cars | orderBy">{{x}}</li>
De forma predeterminada, las cadenas se ordenan alfabéticamente y los números se ordenan numéricamente.
Si tienes esta matriz con claves:
customers = [
{"name" : "Bottom-Dollar Marketse" ,"city" : "Tsawassen"},
{"name" : "Alfreds Futterkiste", "city" : "Berlin"},
{"name" : "Bon app", "city" : "Marseille"},
{"name" : "Cactus Comidas para llevar", "city" : "Buenos Aires"},
{"name" : "Bolido Comidas preparadas", "city" : "Madrid"},
{"name" : "Around the Horn", "city" : "London"},
{"name" : "B''s Beverages", "city" : "London"}
];
Utilizar:
Ordenar la matriz por orden de "ciudad" DESC:
<li ng-repeat="x in customers | orderBy : ''-city''">{{x.name + ", " + x.city}}</li>
Ordenar la matriz por "ciudad":
<li ng-repeat="x in customers | orderBy : ''city''">{{x.name + ", " + x.city}}</li>