Кастомные Pipes в Angular
16 Апреля 2019
следующая статья
Приводить информацию к определенному общему виду в Angular намного проще, чем во многих других фреймворках. На самом деле это важная деталь, поскольку для каждого отдельного проекта требования могут быть абсолютно разными. Например пользователю нужно видеть дату в формате: 14 апреля 1976, а в чистом, не форматированном виде она выглядит вот так:
Fri Apr 14 1976 00:00:00 GMT-0700 (Pacific Daylight Time)
В самом Angular для решения этого и подобных вопросов, есть такой инструмент как Pipes. Название оправдывает принцип деятельности: мы забрасываем в “трубу” разные данные и на другом конце из нее вылетает то, что нам нужно.
Пример неформатированного вивода:
Ваш день рождения: {{ birthday }}
Пример форматированного вывода с использованием Pipes:
Ваш день рождения: {{ birthday | data }}
Уже готовых Pipes в Angular существует целый набор, подробно о котором можно узнать в документации.
Монтируем трубопровод
Конечно, готовые решения подходят далеко не всем и не всегда. В случае, когда нужный функционал не предусмотрен, “трубу” можно без затруднений создать самостоятельно. Давайте рассмотрим на конкретном примере.
Допустим у нас есть размер файла в байтах, а нужно реализовать вывод, который базируется на размере и приводит его к нужному префиксу Kb/Mb/Gb/Tb. Чтоб создать свой рipe, сначала создадим файл FileSizePipe.ts где задекларируем класс:
export class FileSizePipe {}
Теперь задекларируем имя нашего pipe с помощью декоратора @Pipe:
import { Pipe } from '@angular/core'; @Pipe({ name: 'filesize' }) export class FileSizePipe {}
С помощью этого имени теперь можно обращаться к нашему pipe из шаблонов компонентов, как в случае с датой:
<p> {{ file.size | filesize }} </p>
И, главное, не забываем подключить все в модуль @NgModule в declaration:
// ... import { FileSizePipe } from './filesize.pipe'; @NgModule({ declarations: [ //...
FileSizePipe,
],
})
export class AppModule {}
Следующим шагом будет имплементация интерфейса PipeTransform:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'filesize' }) export class FileSizePipe implements PipeTransform { transform() {} }
Если вы используете Angular CLI, все манипуляции, которые выложены выше, можно провести одной командой в консоле:
ng generate pipe FileSizePipe
И Angular CLI сделает все за вас. Все нужные надстройки к автогенерации находятся тут.
Далее вся магия заключается в методе transform(), который получает значение и будет возвращать уже форматированое значение приемлемого для нас вида. Теперь давайте сразу добавим нашу логику:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'filesize' }) export class FileSizePipe implements PipeTransform { transform(value: any): string{ let sizes = [' Bytes', ' KB', ' MB', ' GB', ' TB']; let l = 0, n = parseInt(value, 10) || 0; while(n >= 1024 && ++l) n = n/1024; return(n.toFixed(n >= 10 || l < 1 ? 0 : 1) + sizes[l]); } }
Наконец применим именно наш pipe:
import {Component} from '@angular/core'; @Component({ selector: 'app-root', template: '<p> {{ file.size | filesize }} </p>' }) export class AppComponent { file = { size: 649233223 }; }
И посмотрим результат:
619 MB
Совершенствуем метод
Еще несколько слов о методе transform(). Если посмотреть на его структуру, можно заметить и другие аргументы кроме основного значения:
interface PipeTransform { transform(value: any, ...args: any[]): any }
Рассмотрим их применение на нашем прежнем примере. Допустим, мы хотим повторить вывод результата N раз. Тогда при обращении в шаблоне нужно передать второй параметр и это будет выглядеть так:
<p> {{ file.size | filesize:4 }} </p>
Ну и немного допишем наш метод:
transform(value: any, times:number):string{ let sizes = [' Bytes', ' KB', ' MB', ' GB', ' TB']; let l = 0, n = parseInt(value, 10) || 0; while(n >= 1024 && ++l) n = n/1024; return (n.toFixed(n >= 10 || l < 1 ? 0 : 1) + sizes[l]+'. ').repeat(times); }
Теперь в результате мы увидим: 619 MB. 619 MB. 619 MB. 619 MB.
Таким образом вы заметили, что в кастомизации pipes нет ничего сложного. Синтаксис достаточно простой и понятный. Создание своих “труб” может стать весьма занятным делом. А в дальнейшем свои pipes можно будет с легкостью переносить и использовать в других проектах.
Похожие статьи
Записаться на консультацию
Мы свяжемся с вами в течении 10 минут