Angular 2
pipes
Zoeken…
Invoering
De pijp |
karakter wordt gebruikt om pijpen in Angular 2 toe te passen. Pijpen lijken erg op filters in AngularJS omdat ze allebei helpen om de gegevens in een gespecificeerd formaat te transformeren.
parameters
Functie / Parameter | Uitleg |
---|---|
@Pipe ({name, pure}) | metadata voor pijp, moeten onmiddellijk voorafgaan aan pijpklasse |
naam: string | wat u in de sjabloon gaat gebruiken |
puur: boolean | standaard ingesteld op waar, markeer dit als onwaar om je pijp vaker opnieuw te laten evalueren |
transform (waarde, args []?) | de functie die wordt opgeroepen om de waarden in de sjabloon te transformeren |
waarde: elke | de waarde die u wilt transformeren |
args: any [] | de argumenten die u mogelijk nodig heeft in uw transformatie. Markeer optionele args met de? operator zoals so transform (waarde, arg1, arg2?) |
Opmerkingen
Dit onderwerp behandelt Angular2-buizen , een mechanisme voor het transformeren en opmaken van gegevens in HTML-sjablonen in een Angular2-toepassing.
Buizen koppelen
Buizen kunnen worden geketend.
<p>Today is {{ today | date:'fullDate' | uppercase}}.</p>
Aangepaste buizen
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 { }
Ingebouwde pijpen
Angular2 wordt geleverd met een paar ingebouwde pijpen:
Pijp | Gebruik | Voorbeeld |
---|---|---|
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 |
Er zijn anderen. Kijk hier voor hun documentatie.
Voorbeeld
hotel-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;
}
hotel-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>
uitgang
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.
Debuggen met JsonPipe
De JsonPipe kan worden gebruikt voor het debuggen van de status van een gegeven intern.
Code
@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]}};
}
uitgang
Without JSON Pipe:
object
With JSON pipe:
{object:{foo: 'bar', baz: 'qux', nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}}
Wereldwijd beschikbare aangepaste pijp
Om een aangepaste pijp voor de hele applicatie beschikbaar te maken, Tijdens applicatie-bootstrap, uitbreiding van 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
})
]);
Zelfstudie hier: https://scotch.io/tutorials/create-a-globally-available-custom-pipe-in-angle-2
Aangepaste pijp maken
app / 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
}
}
app / 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-waarden uitpakken met async-pijp
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']);
}
Wordt:
<h1>Hello, Misko</h1>
Your Friends are:
<ul>
<li>
Igor
</li>
</ul>
Bestaande buis verlengen
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
}
}
}
Stateful Pipes
Angular 2 biedt twee verschillende soorten pijpen - stateless en stateful. Buizen zijn standaard staatloos. We kunnen echter stateful pipes implementeren door de pure
eigenschap in te stellen op false
. Zoals u kunt zien in de parametersectie, kunt u een name
opgeven en aangeven of de pijp zuiver moet zijn of niet, wat betekent stateful of stateless. Terwijl gegevens door een stateless pipe stromen (wat een pure functie is) die zich niets herinnert, kunnen gegevens worden beheerd en onthouden door stateful pipes. Een goed voorbeeld van een stateful pipe is de AsyncPipe
die wordt geleverd door Angular 2.
Belangrijk
Merk op dat de meeste pijpen in de categorie stateless pijpen moeten vallen. Dat is belangrijk om prestatieredenen, omdat Angular stateless pijpen voor de wijzigingsdetector kan optimaliseren. Gebruik dus voorzichtig pijpen. Over het algemeen heeft de optimalisatie van pijpen in hoek 2 een belangrijke prestatieverbetering ten opzichte van filters in hoek 1.x. In hoek 1 moest de digest-cyclus altijd alle filters opnieuw uitvoeren, ook al zijn de gegevens helemaal niet gewijzigd. In hoek 2 weet de veranderingsdetector, zodra de waarde van een pijp is berekend, deze pijp niet opnieuw te laten draaien, tenzij de invoer verandert.
Implementatie van een stateful pipe
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);
}
}
}
U kunt de pijp vervolgens zoals gewoonlijk gebruiken:
{{ 1000 | countdown:50 }}
{{ 300 | countdown }}
Het is belangrijk dat uw pijp ook de OnDestroy
interface implementeert, zodat u kunt opschonen zodra uw pijp wordt vernietigd. In het bovenstaande voorbeeld is het noodzakelijk om het interval te wissen om geheugenlekken te voorkomen.
Dynamische buis
Gebruiksscenario: een tabelweergave bestaat uit verschillende kolommen met verschillende gegevensindelingen die moeten worden getransformeerd met verschillende pijpen.
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>
Resultaat
| 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 | ---------------------------------------------------------------------
Buis testen
Gegeven een pijp die een string omkeert
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'reverse' })
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Het kan worden getest door het spec-bestand als volgt te configureren
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');
}));
});