Angular não vem com um filtro orderBy pronto para uso, mas se decidirmos que precisamos de um, podemos facilmente fazer um. No entanto, existem algumas advertências que precisamos estar cientes relacionadas à velocidade e à minimização. Ver abaixo.
Um tubo simples seria algo assim.
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)
}
}
Esse tubo aceita uma função de classificação ( fn
) e fornece a ela um valor padrão que classificará uma matriz de primitivas de uma maneira sensata. Temos a opção de substituir esta função de classificação, se desejarmos.
Ele não aceita um nome de atributo como string, porque os nomes de atributo estão sujeitos a minificação. Eles mudarão quando reduzirmos nosso código, mas os minificadores não são inteligentes o suficiente para também reduzir o valor na string do modelo.
Primitivas de classificação (números e strings)
Podemos usar isso para classificar uma matriz de números ou strings usando o comparador padrão:
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']
}
Classificando uma série de objetos
Se quisermos classificar um array de objetos, podemos atribuir a ele uma função de comparador.
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
}
}
Advertências - tubos puros vs. tubos impuros
Angular 2 tem um conceito de tubos puros e impuros.
Um tubo puro otimiza a detecção de alterações usando a identidade do objeto. Isso significa que o pipe só será executado se o objeto de entrada mudar de identidade, por exemplo, se adicionarmos um novo item ao array. Não vai descer aos objetos. Isso significa que, se alterarmos um atributo aninhado: this.cats[2].name = "Fluffy"
por exemplo, o canal não será executado novamente. Isso ajuda o Angular a ser rápido. Os tubos angulares são puros por padrão.
Um tubo impuro, por outro lado, verificará os atributos do objeto. Isso potencialmente o torna muito mais lento. Como não pode garantir o que a função de pipe fará (talvez seja diferente com base na hora do dia, por exemplo), um pipe impuro será executado sempre que ocorrer um evento assíncrono. Isso tornará seu aplicativo consideravelmente mais lento se a matriz for grande.
O tubo acima é puro. Isso significa que ele só será executado quando os objetos na matriz forem imutáveis. Se você trocar um gato, deverá substituir todo o objeto gato por um novo.
this.cats[2] = {name:"Tomy"}
Podemos mudar o que está acima para um cano impuro definindo o 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)
}
}
Este tubo descerá até os objetos, mas será mais lento. Use com cuidado.