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');
}));
});