Angular не поставляется с фильтром orderBy из коробки, но если мы решим, что он нам нужен, мы легко его создадим. Однако есть некоторые предостережения, о которых мы должны знать, связанные со скоростью и минимизацией. Увидеть ниже.
Простая труба будет выглядеть примерно так.
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)
}
}
Этот канал принимает функцию сортировки ( fn
) и дает ей значение по умолчанию, которое будет разумно сортировать массив примитивов. У нас есть возможность переопределить эту функцию сортировки, если мы хотим.
Он не принимает имя атрибута в виде строки, потому что имена атрибутов подлежат минификации. Они изменятся, когда мы минимизируем наш код, но минификаторы недостаточно умны, чтобы также минимизировать значение в строке шаблона.
Сортировка примитивов (числа и строки)
Мы могли бы использовать это для сортировки массива чисел или строк, используя компаратор по умолчанию:
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']
}
Сортировка массива объектов
Если мы хотим отсортировать массив объектов, мы можем дать ему функцию компаратора.
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
}
}
Предостережения - чистые и нечистые трубы
Angular 2 имеет концепцию чистых и нечистых труб.
Чистый канал оптимизирует обнаружение изменений с помощью идентификации объекта. Это означает, что конвейер будет работать только в том случае, если входной объект изменит идентификатор, например, если мы добавим новый элемент в массив. Он не будет спускаться в предметы. Это означает, что если мы изменим вложенный атрибут: this.cats[2].name = "Fluffy"
например, конвейер не будет запускаться повторно. Это помогает Angular быть быстрым. Угловые трубы по умолчанию чистые.
С другой стороны, нечистый канал будет проверять атрибуты объекта. Это потенциально делает его намного медленнее. Поскольку он не может гарантировать, что будет делать функция конвейера (возможно, он по-разному сортируется в зависимости от времени суток, например), нечистый канал будет запускаться каждый раз, когда происходит асинхронное событие. Это значительно замедлит работу вашего приложения, если массив большой.
Труба выше чистая. Это означает, что он будет работать только в том случае, если объекты в массиве неизменны. Если вы меняете кота, вы должны заменить весь объект кота новым.
this.cats[2] = {name:"Tomy"}
Мы можем изменить указанное выше на нечистую трубу, установив чистый атрибут:
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)
}
}
Эта труба будет спускаться в объекты, но будет медленнее. Используйте с осторожностью.