navigationend - Angular 2 ordenar y filtrar
router events angular 6 (6)
En Angularjs 1 es posible ordenar y filtrar de la siguiente manera:
<ul ng-repeat="friend in friends | filter:query | orderBy: ''name'' ">
<li>{{friend.name}}</li>
</ul>
Pero no pude encontrar ningún ejemplo de cómo hacer esto en Angularjs 2.0. Mi pregunta es cómo ordenar y filtrar en Angularjs 2.0? Si aún no es compatible, ¿alguien sabe cuándo o si se colocará en Angularjs 2.0?
Aquí hay una tubería de filtro simple para una matriz de objetos que contienen atributos con valores de cadena (ES6)
filter-array-pipe.js
import {Pipe} from ''angular2/core'';
// # Filter Array of Objects
@Pipe({ name: ''filter'' })
export class FilterArrayPipe {
transform(value, args) {
if (!args[0]) {
return value;
} else if (value) {
return value.filter(item => {
for (let key in item) {
if ((typeof item[key] === ''string'' || item[key] instanceof String) &&
(item[key].indexOf(args[0]) !== -1)) {
return true;
}
}
});
}
}
}
Su componente
myobjComponent.js
import {Component} from ''angular2/core'';
import {HTTP_PROVIDERS, Http} from ''angular2/http'';
import {FilterArrayPipe} from ''filter-array-pipe'';
@Component({
templateUrl: ''myobj.list.html'',
providers: [HTTP_PROVIDERS],
pipes: [FilterArrayPipe]
})
export class MyObjList {
static get parameters() {
return [[Http]];
}
constructor(_http) {
_http.get(''/api/myobj'')
.map(res => res.json())
.subscribe(
data => this.myobjs = data,
err => this.logError(err))
);
}
resetQuery(){
this.query = '''';
}
}
En su plantilla
myobj.list.html
<input type="text" [(ngModel)]="query" placeholder="... filter" >
<div (click)="resetQuery()"> <span class="icon-cross"></span> </div>
</div>
<ul><li *ngFor="#myobj of myobjs| filter:query">...<li></ul>
Debe crear su propia tubería para la ordenación de matrices, aquí hay un ejemplo de cómo puede hacer eso.
<li *ngFor="#item of array | arraySort:''-date''">{{item.name}} {{item.date | date:''medium'' }}</li>
Este es mi tipo. Hará la ordenación por número, por cadena y por fecha.
import { Pipe , PipeTransform } from "@angular/core";
@Pipe({
name: ''sortPipe''
})
export class SortPipe implements PipeTransform {
transform(array: Array<string>, key: string): Array<string> {
console.log("Entered in pipe******* "+ key);
if(key === undefined || key == '''' ){
return array;
}
var arr = key.split("-");
var keyString = arr[0]; // string or column name to sort(name or age or date)
var sortOrder = arr[1]; // asc or desc order
var byVal = 1;
array.sort((a: any, b: any) => {
if(keyString === ''date'' ){
let left = Number(new Date(a[keyString]));
let right = Number(new Date(b[keyString]));
return (sortOrder === "asc") ? right - left : left - right;
}
else if(keyString === ''name''){
if(a[keyString] < b[keyString]) {
return (sortOrder === "asc" ) ? -1*byVal : 1*byVal;
} else if (a[keyString] > b[keyString]) {
return (sortOrder === "asc" ) ? 1*byVal : -1*byVal;
} else {
return 0;
}
}
else if(keyString === ''age''){
return (sortOrder === "asc") ? a[keyString] - b[keyString] : b[keyString] - a[keyString];
}
});
return array;
}
}
Esto no se agrega de fábrica porque el equipo de Angular quiere que Angular 2 se ejecute minimizado. OrderBy se escapa de la reflexión que rompe con la minificación. Mira la respuesta de Miško Heverey al respecto.
Me he tomado el tiempo para crear una tubería OrderBy que admita tanto matrices simples como multidimensionales. También admite poder ordenar en múltiples columnas de la matriz multidimensional.
<li *ngFor="let person of people | orderBy : [''-lastName'', ''age'']">{{person.firstName}} {{person.lastName}}, {{person.age}}</li>
Esta tubería permite agregar más elementos a la matriz después de representar la página, y aún así ordenar las matrices con los nuevos elementos correctamente.
Tengo un artículo sobre el proceso aquí .
Y aquí hay una demostración en funcionamiento: http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby y https://plnkr.co/edit/DHLVc0?p=info
EDITAR: Se agregó una nueva demostración a http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby
EDIT 2: ngFor actualizado a la nueva sintaxis
No es compatible con el diseño. La tubería sortBy puede causar problemas de rendimiento reales para una aplicación de escala de producción. Este fue un problema con la versión angular 1.
No debe crear una función de clasificación personalizada. En su lugar, debe ordenar su matriz primero en el archivo de mecanografía y luego mostrarla. Si es necesario actualizar el orden cuando, por ejemplo, se selecciona un menú desplegable, haga que esta selección desplegable active una función y llame a su función de clasificación desde allí. Esta función de clasificación se puede extraer a un servicio para que se pueda reutilizar. De esta manera, la clasificación solo se aplicará cuando sea necesario y el rendimiento de su aplicación será mucho mejor.
Una tubería toma datos como entrada y los transforma en una salida deseada.
Agregue este archivo de canalización:
orderby.ts
dentro de su carpeta
/app
.
//The pipe class implements the PipeTransform interface''s transform method that accepts an input value and an optional array of parameters and returns the transformed value.
import { Pipe,PipeTransform } from "angular2/core";
//We tell Angular that this is a pipe by applying the @Pipe decorator which we import from the core Angular library.
@Pipe({
//The @Pipe decorator takes an object with a name property whose value is the pipe name that we''ll use within a template expression. It must be a valid JavaScript identifier. Our pipe''s name is orderby.
name: "orderby"
})
export class OrderByPipe implements PipeTransform {
transform(array:Array<any>, args?) {
// Check if array exists, in this case array contains articles and args is an array that has 1 element : !id
if(array) {
// get the first element
let orderByValue = args[0]
let byVal = 1
// check if exclamation point
if(orderByValue.charAt(0) == "!") {
// reverse the array
byVal = -1
orderByValue = orderByValue.substring(1)
}
console.log("byVal",byVal);
console.log("orderByValue",orderByValue);
array.sort((a: any, b: any) => {
if(a[orderByValue] < b[orderByValue]) {
return -1*byVal;
} else if (a[orderByValue] > b[orderByValue]) {
return 1*byVal;
} else {
return 0;
}
});
return array;
}
//
}
}
En su archivo de componente (app.component.ts), importe la tubería que acaba de agregar usando:
import {OrderByPipe} from ''./orderby'';
Luego, agregue
*ngFor="#article of articles | orderby:''id''"
dentro de su plantilla si desea ordenar sus artículos por id en orden ascendente u
orderby:''!id''"
en orden descendente.
Agregamos parámetros a una tubería siguiendo el nombre de la tubería con dos puntos (:) y luego el valor del parámetro
Debemos enumerar nuestra tubería en la matriz de tuberías del decorador @Component.
pipes: [ OrderByPipe ]
.
import {Component, OnInit} from ''angular2/core'';
import {OrderByPipe} from ''./orderby'';
@Component({
selector: ''my-app'',
template: `
<h2>orderby-pipe by N2B</h2>
<p *ngFor="#article of articles | orderby:''id''">
Article title : {{article.title}}
</p>
`,
pipes: [ OrderByPipe ]
})
export class AppComponent{
articles:Array<any>
ngOnInit(){
this.articles = [
{
id: 1,
title: "title1"
},{
id: 2,
title: "title2",
}]
}
}
Más información aquí en mi github y esta publicación en mi sitio web