Angular no viene con un filtro orderBy listo para usar, pero si decidimos que necesitamos uno, podemos crear uno fácilmente. Sin embargo, hay algunas advertencias que debemos tener en cuenta en relación con la velocidad y la minificación. Vea abajo.
Una pipa simple se vería así.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'sort'
})
export class SortPipe implements PipeTransform {
transform(ary: any, fn: Function = (a,b) => a > b ? 1 : -1): any {
return ary.sort(fn)
}
}
Esta tubería acepta una función de clasificación ( fn
) y le da un valor predeterminado que clasificará una matriz de primitivas de una manera sensata. Tenemos la opción de anular esta función de clasificación si lo deseamos.
No acepta un nombre de atributo como una cadena, porque los nombres de atributo están sujetos a minificación. Cambiarán cuando minimicemos nuestro código, pero los minificadores no son lo suficientemente inteligentes como para minimizar también el valor en la cadena de la plantilla.
Ordenar primitivas (números y cadenas)
Podríamos usar esto para ordenar una matriz de números o cadenas usando el comparador predeterminado:
import { Component } from '@angular/core';
@Component({
selector: 'cat',
template: `
{{numbers | sort}}
{{strings | sort}}
`
})
export class CatComponent
numbers:Array<number> = [1,7,5,6]
stringsArray<string> = ['cats', 'hats', 'caveats']
}
Ordenar una matriz de objetos
Si queremos ordenar una matriz de objetos, podemos darle una función de comparación.
import { Component } from '@angular/core';
@Component({
selector: 'cat',
template: `
{{cats | sort:byName}}
`
})
export class CatComponent
cats:Array<Cat> = [
{name: "Missy"},
{name: "Squoodles"},
{name: "Madame Pompadomme"}
]
byName(a,b) {
return a.name > b.name ? 1 : -1
}
}
Advertencias: pipas puras vs impuras
Angular 2 tiene un concepto de tuberías puras e impuras.
Una tubería pura optimiza la detección de cambios utilizando la identidad del objeto. Esto significa que la tubería solo se ejecutará si el objeto de entrada cambia de identidad, por ejemplo, si agregamos un nuevo elemento a la matriz. No descenderá a los objetos. Esto significa que si cambiamos un atributo anidado: this.cats[2].name = "Fluffy"
por ejemplo, la tubería no se volverá a ejecutar. Esto ayuda a Angular a ser rápido. Las tuberías angulares son puras por defecto.
Una tubería impura, por otro lado, verificará los atributos del objeto. Esto potencialmente lo hace mucho más lento. Debido a que no puede garantizar lo que hará la función de tubería (tal vez se clasificó de manera diferente según la hora del día, por ejemplo), una tubería impura se ejecutará cada vez que ocurra un evento asincrónico. Esto ralentizará considerablemente su aplicación si la matriz es grande.
La pipa de arriba es pura. Esto significa que solo se ejecutará cuando los objetos de la matriz sean inmutables. Si cambia un gato, debe reemplazar todo el objeto gato por uno nuevo.
this.cats[2] = {name:"Tomy"}
Podemos cambiar lo anterior a una tubería impura estableciendo el atributo puro:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'sort',
pure: false
})
export class SortPipe implements PipeTransform {
transform(ary: any, fn: Function = (a,b) => a > b ? 1 : -1): any {
return ary.sort(fn)
}
}
Esta tubería descenderá hacia los objetos, pero será más lenta. Úselo con precaución.