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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow