Sök…


Introduktion

Röret | tecken används för att applicera rör i Angular 2. Rör liknar filter i AngularJS eftersom de båda hjälper till att omvandla data till ett specificerat format.

parametrar

Funktion / parameter Förklaring
@ Pipe ({name, pure}) metadata för rör, måste omedelbart föregå rörklass
namn: sträng vad du kommer att använda i mallen
ren: boolean som standard är sant, markera detta som falskt för att ditt rör ska utvärderas oftare
transform (värde, args []?) funktionen som kallas för att transformera värdena i mallen
värde: valfri värdet som du vill transformera
args: alla [] de argument som du kanske behöver inkludera i din transform. Markera valfritt args med? operatör som så transformera (värde, arg1, arg2?)

Anmärkningar

Detta ämne täcker Angular2 Pipes , en mekanism för att transformera och formatera data i HTML-mallar i en Angular2-applikation.

Kedjeledningar

Rör kan kedjas.

<p>Today is {{ today | date:'fullDate' | uppercase}}.</p>

Anpassade rör

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 { }

Inbyggda rör

Angular2 levereras med några inbyggda rör:

Rör Användande Exempel
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

Det finns andra. Titta här för deras dokumentation.

Exempel

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>

Produktion

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.

Felsökning med JsonPipe

JsonPipe kan användas för att felsöka tillståndet för varje internt.

Koda

@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]}};
}

Produktion

Without JSON Pipe:
object
With JSON pipe:
{object:{foo: 'bar', baz: 'qux', nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}}

Globalt tillgängligt anpassat rör

För att göra en anpassad rör tillgänglig applikation bred, Under applikationsstartsträcka, utökar 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
        })
]);

Handledning här: https://scotch.io/tutorials/create-a-globally-available-custom-pipe-in-angular-2

Skapa anpassade rör

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{ }

Ta bort asynkvärden med asynkröret

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

blir:

<h1>Hello, Misko</h1>
Your Friends are:
<ul>
  <li>
    Igor
  </li>
</ul>

Utöka ett befintligt rör

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
    }
  }
}

Statliga rör

Angular 2 erbjuder två olika typer av rör - statslösa och statliga. Rör är standardlösa som standard. Men vi kan implementera tillståndsrör genom att ställa den pure egenskapen till false . Som du kan se i parameteravsnittet kan du ange ett name och förklara om röret ska vara rent eller inte, vilket betyder statligt eller statligt. Medan data flyter genom ett statslöst rör (som är en ren funktion) som inte kommer ihåg något, kan data hanteras och komma ihåg av statliga rör. Ett bra exempel på ett tillräckligt rör är AsyncPipe som tillhandahålls av Angular 2.

Viktig

Lägg märke till att de flesta rör bör tillhöra kategorin statslösa rör. Det är viktigt av prestandaskäl eftersom Angular kan optimera statslösa rör för förändringsdetektorn. Så använd försiktiga rör försiktigt. Generellt sett har optimering av rör i Angular 2 en stor prestandaförbättring jämfört med filter i Angular 1.x. I vinkel 1 måste matsmältningscykeln alltid köra alla filter trots att uppgifterna inte har ändrats alls. I vinkel 2, när ett rörs värde har beräknats, vet förändringsdetektorn att inte köra detta rör igen om ingången ändras.

Implementering av ett tillräckligt rör

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

Du kan sedan använda röret som vanligt:

{{ 1000 | countdown:50 }}
{{ 300 | countdown }}

Det är viktigt att ditt rör också implementerar OnDestroy gränssnittet så att du kan rensa när ditt rör förstörs. I exemplet ovan är det nödvändigt att rensa intervallet för att undvika minnesläckor.

Dynamisk rör

Använd fallsscenario: En tabellvy består av olika kolumner med olika dataformat som måste omvandlas med olika rör.

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>

Resultat

| 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   |
---------------------------------------------------------------------

Testa ett rör

Med tanke på ett rör som vänder tillbaka en sträng

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'reverse' })
export class ReversePipe implements PipeTransform {
  transform(value: string): string {
    return value.split('').reverse().join('');
  }
}

Det kan testas genom att konfigurera spec-filen så här

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow