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


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow