Angular 2
трубы
Поиск…
Вступление
Труба |
character используется для применения труб в Angular 2. Трубы очень похожи на фильтры в AngularJS, поскольку они помогают преобразовать данные в заданный формат.
параметры
Функция / параметр | объяснение |
---|---|
@Pipe ({name, pure}) | метаданные для трубы, должны немедленно предшествовать классу труб |
имя: строка | что вы будете использовать внутри шаблона |
pure: boolean | по умолчанию - true, отметьте это как false, чтобы ваш канал повторно оценивался чаще |
transform (значение, args []?) | функция, вызываемая для преобразования значений в шаблон |
значение: любое | значение, которое вы хотите преобразовать |
args: any [] | аргументы, которые могут понадобиться вам в вашем преобразовании. Отметить необязательные аргументы с? оператор вроде так преобразует (значение, arg1, arg2?) |
замечания
В этом разделе рассматривается Angular2 Pipes , механизм преобразования и форматирования данных в HTML-шаблонах в приложении Angular2.
Цепные трубы
Трубы могут быть прикованы.
<p>Today is {{ today | date:'fullDate' | uppercase}}.</p>
Пользовательские трубы
my.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'myPipe'})
export class MyPipe implements PipeTransform {
transform(value:any, args?: any):string {
let transformedValue = value; // implement your transformation logic here
return transformedValue;
}
}
my.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `{{ value | myPipe }}`
})
export class MyComponent {
public value:any;
}
my.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MyComponent } from './my.component';
import { MyPipe } from './my.pipe';
@NgModule({
imports: [
BrowserModule,
],
declarations: [
MyComponent,
MyPipe
],
})
export class MyModule { }
Встроенные трубы
Angular2 поставляется с несколькими встроенными трубами:
труба | использование | пример |
---|---|---|
DatePipe | date | {{ dateObj | date }} // output is 'Jun 15, 2015' |
UpperCasePipe | uppercase | {{ value | uppercase }} // output is 'SOMETEXT' |
LowerCasePipe | lowercase | {{ value | lowercase }} // output is 'sometext' |
CurrencyPipe | currency | {{ 31.00 | currency:'USD':true }} // output is '$31' |
PercentPipe | percent | {{ 0.03 | percent }} //output is %3 |
Есть и другие. Посмотрите здесь их документацию.
пример
отель-reservation.component.ts
import { Component } from '@angular/core';
@Component({
moduleId: module.id,
selector: 'hotel-reservation',
templateUrl: './hotel-reservation.template.html'
})
export class HotelReservationComponent {
public fName: string = 'Joe';
public lName: string = 'SCHMO';
public reservationMade: string = '2016-06-22T07:18-08:00'
public reservationFor: string = '2025-11-14';
public cost: number = 99.99;
}
Гостинично-reservation.template.html
<div>
<h1>Welcome back {{fName | uppercase}} {{lName | lowercase}}</h1>
<p>
On {reservationMade | date} at {reservationMade | date:'shortTime'} you
reserved room 205 for {reservationDate | date} for a total cost of
{cost | currency}.
</p>
</div>
Выход
Welcome back JOE schmo
On Jun 26, 2016 at 7:18 you reserved room 205 for Nov 14, 2025 for a total cost of
$99.99.
Отладка с помощью JsonPipe
JsonPipe может использоваться для отладки состояния любого заданного внутреннего.
Код
@Component({
selector: 'json-example',
template: `<div>
<p>Without JSON pipe:</p>
<pre>{{object}}</pre>
<p>With JSON pipe:</p>
<pre>{{object | json}}</pre>
</div>`
})
export class JsonPipeExample {
object: Object = {foo: 'bar', baz: 'qux', nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}};
}
Выход
Without JSON Pipe:
object
With JSON pipe:
{object:{foo: 'bar', baz: 'qux', nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}}
Доступная по всему миру пользовательская труба
Чтобы сделать доступное приложение доступным пользователем, во время загрузки загрузочного диска, PLATFORM_PIPES.
import { bootstrap } from '@angular/platform-browser-dynamic';
import { provide, PLATFORM_PIPES } from '@angular/core';
import { AppComponent } from './app.component';
import { MyPipe } from './my.pipe'; // your custom pipe
bootstrap(AppComponent, [
provide(PLATFORM_PIPES, {
useValue: [
MyPipe
],
multi: true
})
]);
Учебник здесь: https://scotch.io/tutorials/create-a-globally-available-custom-pipe-in-angular-2
Создание пользовательских труб
приложение / pipes.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'truthy'})
export class Truthy implements PipeTransform {
transform(value: any, truthy: string, falsey: string): any {
if (typeof value === 'boolean'){return value ? truthy : falsey;}
else return value
}
}
приложение / My-component.component.ts
import { Truthy} from './pipes.pipe';
@Component({
selector: 'my-component',
template: `
<p>{{value | truthy:'enabled':'disabled' }}</p>
`,
pipes: [Truthy]
})
export class MyComponent{ }
Отменить асинхронные значения с помощью async-канала
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
@Component({
selector: 'async-stuff',
template: `
<h1>Hello, {{ name | async }}</h1>
Your Friends are:
<ul>
<li *ngFor="let friend of friends | async">
{{friend}}
</li>
</ul>
`
})
class AsyncStuffComponent {
name = Promise.resolve('Misko');
friends = Observable.of(['Igor']);
}
становится:
<h1>Hello, Misko</h1>
Your Friends are:
<ul>
<li>
Igor
</li>
</ul>
Расширение существующей трубы
import { Pipe, PipeTransform } from '@angular/core';
import { DatePipe } from '@angular/common'
@Pipe({name: 'ifDate'})
export class IfDate implements PipeTransform {
private datePipe: DatePipe = new DatePipe();
transform(value: any, pattern?:string) : any {
if (typeof value === 'number') {return value}
try {
return this.datePipe.transform(value, pattern)
} catch(err) {
return value
}
}
}
Состоятельные трубы
Угловой 2 предлагает два разных типа труб - без гражданства и состояния. По умолчанию они не имеют апатридов. Тем не менее, мы можем реализовать протоколы stateful, установив для свойства pure
значение false
. Как вы можете видеть в разделе параметров, вы можете указать name
и объявить, должен ли канал быть чистым или нет, что означает состояние или без состояния. В то время как данные передаются по безстоящей трубе (которая является чистой функцией), которая ничего не помнит, данные могут управляться и запоминаться с помощью протоколов stateful. Хорошим примером трубы с AsyncPipe
состояния является AsyncPipe
, предоставляемый Angular 2.
Важный
Обратите внимание, что большинство труб должно относиться к категории безгосударственных труб. Это важно по соображениям производительности, так как Angular может оптимизировать трубы без гражданства для детектора изменений. Поэтому осторожно используйте стоп-сигналы. В общем, оптимизация труб в Angular 2 имеет значительное повышение производительности по сравнению с фильтрами в Angular 1.x. В Angular 1 цикл дайджеста всегда должен был повторно запускать все фильтры, даже если данные вообще не изменились. В Угловом 2, когда значение трубы было вычислено, детектор изменений знает, что он не запускает этот трубопровод снова, если вход не изменится.
Реализация трубы с отслеживанием состояния
import {Pipe, PipeTransform, OnDestroy} from '@angular/core';
@Pipe({
name: 'countdown',
pure: false
})
export class CountdownPipe implements PipeTransform, OnDestroy {
private interval: any;
private remainingTime: number;
transform(value: number, interval: number = 1000): number {
if (!parseInt(value, 10)) {
return null;
}
if (typeof this.remainingTime !== 'number') {
this.remainingTime = parseInt(value, 10);
}
if (!this.interval) {
this.interval = setInterval(() => {
this.remainingTime--;
if (this.remainingTime <= 0) {
this.remainingTime = 0;
clearInterval(this.interval);
delete this.interval;
}
}, interval);
}
return this.remainingTime;
}
ngOnDestroy(): void {
if (this.interval) {
clearInterval(this.interval);
}
}
}
Затем вы можете использовать трубу, как обычно:
{{ 1000 | countdown:50 }}
{{ 300 | countdown }}
Важно, что ваша труба также реализует интерфейс OnDestroy
поэтому вы можете очистить ее, как только ваша труба будет уничтожена. В приведенном выше примере необходимо очистить интервал, чтобы избежать утечек памяти.
Динамическая труба
Пример сценария использования: представление таблицы состоит из разных столбцов с различным форматом данных, которые необходимо преобразовать с помощью разных каналов.
table.component.ts
... import { DYNAMIC_PIPES } from '../pipes/dynamic.pipe.ts'; @Component({ ... pipes: [DYNAMIC_PIPES] }) export class TableComponent { ... // pipes to be used for each column table.pipes = [ null, null, null, 'humanizeDate', 'statusFromBoolean' ], table.header = [ 'id', 'title', 'url', 'created', 'status' ], table.rows = [ [ 1, 'Home', 'home', '2016-08-27T17:48:32', true ], [ 2, 'About Us', 'about', '2016-08-28T08:42:09', true ], [ 4, 'Contact Us', 'contact', '2016-08-28T13:28:18', false ], ... ] ... }
dynamic.pipe.ts
import { Pipe, PipeTransform } from '@angular/core'; // Library used to humanize a date in this example import * as moment from 'moment'; @Pipe({name: 'dynamic'}) export class DynamicPipe implements PipeTransform { transform(value:string, modifier:string) { if (!modifier) return value; // Evaluate pipe string return eval('this.' + modifier + '(\'' + value + '\')') } // Returns 'enabled' or 'disabled' based on input value statusFromBoolean(value:string):string { switch (value) { case 'true': case '1': return 'enabled'; default: return 'disabled'; } } // Returns a human friendly time format e.g: '14 minutes ago', 'yesterday' humanizeDate(value:string):string { // Humanize if date difference is within a week from now else returns 'December 20, 2016' format if (moment().diff(moment(value), 'days') < 8) return moment(value).fromNow(); return moment(value).format('MMMM Do YYYY'); } } export const DYNAMIC_PIPES = [DynamicPipe];
table.component.html
<table> <thead> <td *ngFor="let head of data.header">{{ head }}</td> </thead> <tr *ngFor="let row of table.rows; let i = index"> <td *ngFor="let column of row">{{ column | dynamic:table.pipes[i] }}</td> </tr> </table>
Результат
| ID | Page Title | Page URL | Created | Status | --------------------------------------------------------------------- | 1 | Home | home | 4 minutes ago | Enabled | | 2 | About Us | about | Yesterday | Enabled | | 4 | Contact Us | contact | Yesterday | Disabled | ---------------------------------------------------------------------
Тестирование трубы
С учетом трубы, которая обращает строку
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'reverse' })
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Его можно протестировать, настроив файл спецификации, как это
import { TestBed, inject } from '@angular/core/testing';
import { ReversePipe } from './reverse.pipe';
describe('ReversePipe', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ReversePipe],
});
});
it('should be created', inject([ReversePipe], (reversePipe: ReversePipe) => {
expect(reversePipe).toBeTruthy();
}));
it('should reverse a string', inject([ReversePipe], (reversePipe: ReversePipe) => {
expect(reversePipe.transform('abc')).toEqual('cba');
}));
});