Поиск…


Вступление

Труба | character используется для применения труб в Angular 2. Трубы очень похожи на фильтры в AngularJS, поскольку они помогают преобразовать данные в заданный формат.

параметры

Функция / параметр объяснение
@Pipe ({name, pure}) метаданные для трубы, должны немедленно предшествовать классу труб
имя: строка что вы будете использовать внутри шаблона
pure: boolean по умолчанию - true, отметьте это как false, чтобы ваш канал повторно оценивался чаще
transform (значение, args []?) функция, вызываемая для преобразования значений в шаблон
значение: любое значение, которое вы хотите преобразовать
args: any [] аргументы, которые могут понадобиться вам в вашем преобразовании. Отметить необязательные аргументы с? оператор вроде так преобразует (значение, arg1, arg2?)

замечания

В этом разделе рассматривается Angular2 Pipes , механизм преобразования и форматирования данных в HTML-шаблонах в приложении Angular2.

Цепные трубы

Трубы могут быть прикованы.

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

Пользовательские трубы

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

Встроенные трубы

Angular2 поставляется с несколькими встроенными трубами:

труба использование пример
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

Есть и другие. Посмотрите здесь их документацию.

пример

отель-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;
}

Гостинично-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>

Выход

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.

Отладка с помощью JsonPipe

JsonPipe может использоваться для отладки состояния любого заданного внутреннего.

Код

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

Выход

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

Доступная по всему миру пользовательская труба

Чтобы сделать доступное приложение доступным пользователем, во время загрузки загрузочного диска, 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
        })
]);

Учебник здесь: https://scotch.io/tutorials/create-a-globally-available-custom-pipe-in-angular-2

Создание пользовательских труб

приложение / 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
  }
}

приложение / 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-канала

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

становится:

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

Расширение существующей трубы

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

Состоятельные трубы

Угловой 2 предлагает два разных типа труб - без гражданства и состояния. По умолчанию они не имеют апатридов. Тем не менее, мы можем реализовать протоколы stateful, установив для свойства pure значение false . Как вы можете видеть в разделе параметров, вы можете указать name и объявить, должен ли канал быть чистым или нет, что означает состояние или без состояния. В то время как данные передаются по безстоящей трубе (которая является чистой функцией), которая ничего не помнит, данные могут управляться и запоминаться с помощью протоколов stateful. Хорошим примером трубы с AsyncPipe состояния является AsyncPipe , предоставляемый Angular 2.

Важный

Обратите внимание, что большинство труб должно относиться к категории безгосударственных труб. Это важно по соображениям производительности, так как Angular может оптимизировать трубы без гражданства для детектора изменений. Поэтому осторожно используйте стоп-сигналы. В общем, оптимизация труб в Angular 2 имеет значительное повышение производительности по сравнению с фильтрами в Angular 1.x. В Angular 1 цикл дайджеста всегда должен был повторно запускать все фильтры, даже если данные вообще не изменились. В Угловом 2, когда значение трубы было вычислено, детектор изменений знает, что он не запускает этот трубопровод снова, если вход не изменится.

Реализация трубы с отслеживанием состояния

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

Затем вы можете использовать трубу, как обычно:

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

Важно, что ваша труба также реализует интерфейс OnDestroy поэтому вы можете очистить ее, как только ваша труба будет уничтожена. В приведенном выше примере необходимо очистить интервал, чтобы избежать утечек памяти.

Динамическая труба

Пример сценария использования: представление таблицы состоит из разных столбцов с различным форматом данных, которые необходимо преобразовать с помощью разных каналов.

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>

Результат

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

Тестирование трубы

С учетом трубы, которая обращает строку

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

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

Его можно протестировать, настроив файл спецификации, как это

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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow