Angular nie jest dostarczany z filtrem orderBy po wyjęciu z pudełka, ale jeśli zdecydujemy, że go potrzebujemy, możemy go łatwo zrobić. Są jednak pewne zastrzeżenia, o których musimy wiedzieć, jeśli chodzi o szybkość i minifikację. Zobacz poniżej.
Prosta rura wyglądałaby mniej więcej tak.
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)
}
}
Ten potok akceptuje funkcję sortowania ( fn
) i nadaje jej domyślną wartość, która posortuje tablicę prymitywów w rozsądny sposób. Jeśli chcemy, mamy możliwość nadpisania tej funkcji sortowania.
Nie akceptuje nazwy atrybutu jako łańcucha, ponieważ nazwy atrybutów podlegają minifikacji. Zmienią się, gdy zminimalizujemy nasz kod, ale minifier nie są wystarczająco inteligentne, aby również zminimalizować wartość w ciągu szablonu.
Sortowanie prymitywów (liczb i łańcuchów)
Moglibyśmy użyć tego do posortowania tablicy liczb lub ciągów za pomocą domyślnego komparatora:
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']
}
Sortowanie tablicy obiektów
Jeśli chcemy posortować tablicę obiektów, możemy nadać jej funkcję komparatora.
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
}
}
Ostrzeżenia - czyste vs. nieczyste rury
Angular 2 ma koncepcję czystych i nieczystych rur.
Czysta rura optymalizuje wykrywanie zmian przy użyciu tożsamości obiektu. Oznacza to, że potok będzie działał tylko wtedy, gdy obiekt wejściowy zmieni tożsamość, na przykład jeśli dodamy nowy element do tablicy. Nie opuści się w przedmioty. Oznacza to, że jeśli zmienimy zagnieżdżony atrybut: this.cats[2].name = "Fluffy"
na przykład potok nie zostanie ponownie uruchomiony. To pomaga Angularowi być szybkim. Rury kątowe są domyślnie czyste.
Z drugiej strony nieczysta potok sprawdzi atrybuty obiektu. To potencjalnie sprawia, że jest znacznie wolniejszy. Ponieważ nie może zagwarantować, co zrobi funkcja potoku (być może na przykład posortuje inaczej w zależności od pory dnia), zanieczyszczony potok będzie działał za każdym razem, gdy wystąpi zdarzenie asynchroniczne. Spowoduje to znaczne spowolnienie działania aplikacji, jeśli macierz jest duża.
Rura powyżej jest czysta. Oznacza to, że będzie działać tylko wtedy, gdy obiekty w tablicy są niezmienne. Jeśli zmienisz kota, musisz zastąpić cały obiekt kota nowym.
this.cats[2] = {name:"Tomy"}
Możemy zmienić powyższe na nieczystą potokę, ustawiając czysty atrybut:
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)
}
}
Ta rura będzie schodzić w obiekty, ale będzie wolniejsza. Używaj ostrożnie.