Angular 2
Pfeifen
Suche…
Einführung
Das Rohr |
Das Zeichen wird zum Anwenden von Pipes in Angular 2 verwendet. Pipes sind Filtern in AngularJS sehr ähnlich, da beide dazu beitragen, die Daten in ein bestimmtes Format umzuwandeln.
Parameter
Funktion / Parameter | Erläuterung |
---|---|
@Pipe ({Name, rein}) | Metadaten für Pipe müssen unmittelbar vor der Pipe-Klasse liegen |
name: string | was Sie in der Vorlage verwenden werden |
rein: boolean | Wenn der Standardwert "true" ist, markieren Sie dies als "false", damit Ihre Pipe öfter neu bewertet wird |
transform (value, args []?) | Die Funktion, die zum Umwandeln der Werte in der Vorlage aufgerufen wird |
Wert: beliebig | den Wert, den Sie transformieren möchten |
args: any [] | die Argumente, die Sie möglicherweise in Ihre Transformation aufnehmen müssen. Markieren Sie optionale Argumente mit dem? Operator wie so transform (Wert, Arg1, Arg2?) |
Bemerkungen
Dieses Thema behandelt Angular2 Pipes , einen Mechanismus zum Umwandeln und Formatieren von Daten innerhalb von HTML-Vorlagen in einer Angular2-Anwendung.
Verkettung von Rohren
Rohre können angekettet sein.
<p>Today is {{ today | date:'fullDate' | uppercase}}.</p>
Kundenspezifische Rohre
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;
}
}
meine.komponente.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `{{ value | myPipe }}`
})
export class MyComponent {
public value:any;
}
mein.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 { }
Eingebaute Pfeifen
Angular2 wird mit ein paar eingebauten Rohren geliefert:
Rohr | Verwendungszweck | Beispiel |
---|---|---|
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 |
Da sind andere. Hier finden Sie ihre Dokumentation.
Beispiel
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>
Ausgabe
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 mit JsonPipe
Das JsonPipe kann zum Debuggen des Zustands eines beliebigen internen verwendet werden.
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]}};
}
Ausgabe
Without JSON Pipe:
object
With JSON pipe:
{object:{foo: 'bar', baz: 'qux', nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}}
Weltweit verfügbares Custom Pipe
Um eine benutzerdefinierte Pipe für die gesamte Anwendung verfügbar zu machen, erweitern Sie PLATFORM_PIPES während des Anwendungs-Bootstraps.
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
})
]);
Tutorial hier: https://scotch.io/tutorials/create-a-globally-available-custom-pipe-in-angular-2
Benutzerdefiniertes Rohr erstellen
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 / meine-Komponente.Komponente.ts
import { Truthy} from './pipes.pipe';
@Component({
selector: 'my-component',
template: `
<p>{{value | truthy:'enabled':'disabled' }}</p>
`,
pipes: [Truthy]
})
export class MyComponent{ }
Async-Werte mit Async-Pipe auspacken
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']);
}
Wird:
<h1>Hello, Misko</h1>
Your Friends are:
<ul>
<li>
Igor
</li>
</ul>
Bestehendes Rohr verlängern
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 bietet zwei verschiedene Arten von Rohren an - zustandslos und zustandsbehaftet. Pipes sind standardmäßig zustandslos. Stateful-Pipes können jedoch implementiert werden, indem die pure
-Eigenschaft auf false
. Wie Sie im Parameterabschnitt sehen können, können Sie einen name
angeben und angeben, ob die Pipe rein sein soll oder nicht, dh stateful oder zustandslos. Während Daten durch eine zustandslose Pipe (eine reine Funktion) fließen, die sich an nichts erinnert, können Daten von Stateful-Pipe verwaltet und gespeichert werden. Ein gutes Beispiel für eine Stateful-Pipe ist die AsyncPipe
, die von Angular 2 bereitgestellt wird.
Wichtig
Beachten Sie, dass die meisten Rohre in die Kategorie zustandslose Rohre fallen sollten. Dies ist aus Leistungsgründen wichtig, da Angular zustandslose Rohre für den Änderungsdetektor optimieren kann. Verwenden Sie daher Stateful-Pipes vorsichtig. Im Allgemeinen bietet die Optimierung von Rohren in Angular 2 eine wesentliche Verbesserung der Leistung gegenüber Filtern in Angular 1.x. In Winkel 1 musste der Digest-Zyklus immer alle Filter erneut ausführen, auch wenn sich die Daten überhaupt nicht geändert haben. In Winkel 2 kann der Änderungsdetektor nach der Berechnung eines Pipe-Werts diese Pipe nicht erneut ausführen, wenn sich die Eingabe nicht ändert.
Implementierung einer 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);
}
}
}
Sie können die Pipe dann wie gewohnt verwenden:
{{ 1000 | countdown:50 }}
{{ 300 | countdown }}
Es ist wichtig, dass Ihre Pipe auch die OnDestroy
Schnittstelle implementiert, damit Sie aufräumen können, sobald Ihre Pipe zerstört ist. In dem obigen Beispiel muss das Intervall gelöscht werden, um Speicherverluste zu vermeiden.
Dynamisches Rohr
Anwendungsfall: Eine Tabellensicht besteht aus verschiedenen Spalten mit unterschiedlichen Datenformaten, die mit unterschiedlichen Pipes umgewandelt werden müssen.
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 ], ... ] ... }
dynamische.rohr.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>
Ergebnis
| 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 | ---------------------------------------------------------------------
Eine Pfeife testen
Gegeben eine Pipe, die eine Zeichenkette umkehrt
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'reverse' })
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Es kann getestet werden, die Spec-Datei auf diese Weise zu konfigurieren
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');
}));
});