Кутовий - використовуйте труби в сервісах і компонентах


331

У AngularJS я можу використовувати фільтри (труби) всередині служб та контролерів, використовуючи синтаксис, подібний до цього:

$filter('date')(myDate, 'yyyy-MM-dd');

Чи можна використовувати труби в таких службах / компонентах як у Angular?


1
для кутових 8 Перевірте цей підручник із вбудованих та спеціальних труб freakyjolly.com/angular-8-pipes-all-type-of-pipes-with-primples
Code Spy

Відповіді:


660

Як зазвичай в Angular, ви можете розраховувати на ін'єкцію залежності:

import { DatePipe } from '@angular/common';

class MyService {

  constructor(private datePipe: DatePipe) {}

  transformDate(date) {
    return this.datePipe.transform(date, 'yyyy-MM-dd');
  }
}

Додайте DatePipeдо списку постачальників послуг у своєму модулі; якщо ви забудете це зробити, ви отримаєте помилку no provider for DatePipe:

providers: [DatePipe,...]

Оновлення Angular 6 : Angular 6 тепер пропонує майже всі функції форматування, які використовуються трубами публічно. Наприклад, тепер ви можете використовувати formatDateфункцію безпосередньо.

import { formatDate } from '@angular/common';

class MyService {

  constructor(@Inject(LOCALE_ID) private locale: string) {}

  transformDate(date) {
    return formatDate(date, 'yyyy-MM-dd', this.locale);
  }
}

Перед Angular 5 : Будьте попереджені, що DatePipeпокладалися на API Intl до версії 5, яка підтримується не всіма браузерами (перевірте таблицю сумісності ).

Якщо ви використовуєте більш старі версії Angular, вам слід додати Intlполіфайл до проекту, щоб уникнути будь-яких проблем. Дивіться це пов'язане питання для більш детальної відповіді.


Що буде результатом використання DatePipe у веб-переглядачі, який не підтримує Intl? Чи є якісь види прокладки / плейфілла для боротьби з відсутністю підтримки?
сумісний з POSIX

Це сумно призведе до помилки і порушить ваш додаток прямо зараз. На трекері Github відкриті проблеми, але схоже, що в даний час немає хорошого поліфіл ...
cexbrayat

4
Схоже, це не працює для користувальницьких труб, які самі використовують інжекцію залежності у свій конструктор. Або я помиляюся?
Мюррей Сміт

1
@JayChase знаходиться в "angular2 / common".
valter.santos.matos

5
@JayChase імпортувати та додавати в розділи постачальника компонентів: `` `імпорт {DatePipe} з '@ angular / common'; @Component ({... провайдери: [..., DatePipe]}) `` `
alx lark

74

Ця відповідь застаріла

рекомендуємо використовувати підхід DI з інших відповідей замість цього підходу

Оригінальна відповідь:

Ви повинні мати можливість використовувати клас безпосередньо

new DatePipe().transform(myDate, 'yyyy-MM-dd');

Наприклад

var raw = new Date(2015, 1, 12);
var formatted = new DatePipe().transform(raw, 'yyyy-MM-dd');
expect(formatted).toEqual('2015-02-12');

2
При використанні Dateконструктора javascript 0базуються місяці . Так 0є січень і 1лютий. Виправлений зниклий безвістиy
SnareChops

24
У випадку, якщо це допомагає будь-якому іншому, труба з датою імпортується із "angular2 / common".
сумісний з POSIX

1
Фрагмент коду не error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'string'.var formatted = new DatePipe().transform(raw, ['yyyy-MM-dd']);
збирається

10
Тепер випущено Angular v2.0.0, і ви можете ввести цю трубу. Спочатку додайте до NgModule:, @NgModule({ providers:[DatePipe] })потім у своєму класі імпортуйте та constructor( private datePipe: DatePipe ){}
введіть

2
тим часом Angular2 DatePipe очікує Locale_ID як аргумент конструктора. Отже, якщо ви спробуєте використовувати його безпосередньо, вам доведеться надати виправлення Locale_ID, і для цього додатки Locale_ID більше не будуть приймати. Тому я НЕ рекомендую йти цим шляхом.
Е. Хайн

17

Так, це можливо за допомогою простої спеціальної труби. Перевагою використання спеціальної труби є те, що якщо нам потрібно буде оновити формат дати в майбутньому, ми можемо перейти і оновити один файл.

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

@Pipe({
    name: 'dateFormatPipe',
})
export class dateFormatPipe implements PipeTransform {
    transform(value: string) {
       var datePipe = new DatePipe("en-US");
        value = datePipe.transform(value, 'MMM-dd-yyyy');
        return value;
    }
}

{{currentDate | dateFormatPipe }}

Ви завжди можете використовувати цю трубу в будь-якому місці, компоненті, службі тощо

Наприклад

export class AppComponent {
  currentDate : any;
  newDate : any;
  constructor(){
    this.currentDate = new Date().getTime();
    let dateFormatPipeFilter = new dateFormatPipe();
    this.newDate = dateFormatPipeFilter.transform(this.currentDate);
    console.log(this.newDate);
}

Не забудьте імпортувати залежності.

import { Component } from '@angular/core';
import {dateFormatPipe} from './pipes'

Приклади спеціальних труб та додаткова інформація


1
Це не відповідає на питання, як використовувати труби в складі або службі.
сумісний з POSIX

2
Я вилучу свою позицію, якщо ви оновите свою відповідь, щоб не містити інформацію про те, як створити труби. Питання не має нічого спільного з тим, як їх створити.
сумісний з POSIX

2
@ POSIX-сумісний Як я вже згадував у своїй відповіді, він може повторно використовувати та оновлюватись дуже легко, використовуючи власну трубу. Це може допомогти повною мірою комусь іншому. Голоси другорядні.
Прашобх

1
Це справедливий момент, хоча я все ще думаю, що має сенс принаймні мати частину, яка спочатку відповість на це конкретне питання. Зняття голосу. Дякую за відповідь та відповідь.
сумісний з POSIX

1
Чому ви жорстко кодували "en-US"? Ви не хочете якось вводити?
Герман

15

Інші відповіді не працюють у куті 5?

Я отримав помилку, оскільки DatePipe не є постачальником, тому його не можна вводити. Одне з варіантів - це помістити його як провайдера у ваш модуль додатків, але моїм кращим рішенням було його інстанціювати.

Ігноруйте його там, де потрібно:

Я переглянув вихідний код DatePipe, щоб побачити, як він отримав локаль: https://github.com/angular/angular/blob/5.2.5/packages/common/src/pipes/date_pipe.ts#L15-L174

Я хотів використовувати його в трубі, тому мій приклад - в іншій трубі:

import { Pipe, PipeTransform, Inject, LOCALE_ID } from '@angular/core';
import { DatePipe } from '@angular/common';

@Pipe({
    name: 'when',
})
export class WhenPipe implements PipeTransform {
    static today = new Date((new Date).toDateString().split(' ').slice(1).join(' '));
    datePipe: DatePipe;

    constructor(@Inject(LOCALE_ID) private locale: string) {
        this.datePipe = new DatePipe(locale);
    }
    transform(value: string | Date): string {
        if (typeof(value) === 'string')
            value = new Date(value);

        return this.datePipe.transform(value, value < WhenPipe.today ? 'MMM d': 'shortTime')
    }
}

Ключовим тут є імпорт Inject та LOCALE_ID з ядра кута, а потім введення цього, щоб ви могли надати його DatePipe для правильного інстанції.

Зробіть DatePipe постачальником

У своєму модулі додатків ви також можете додати DatePipe до масиву своїх постачальників так:

import { DatePipe } from '@angular/common';

@NgModule({
    providers: [
        DatePipe
    ]
})

Тепер ви можете просто ввести його у свій конструктор там, де потрібно (як у відповіді cexbrayat).

Підсумок:

Будь-яке рішення спрацювало, я не знаю, який саме кутовий вважатиме найбільш "правильним", але я вирішив створити його вручну, оскільки кутовий не надав датчіп як провайдера.


3
Ви можете зробити це також у постачальника компонентів
Джиммі Кейн

Спасибі, ваша відповідь є найбільш вичерпною. Я шукаю деякі ресурси щодо відмінностей між інстанцією труби новою або залежністю, яка вводить її безпосередньо, і додаю її постачальникам, і нічого не можу знайти. Я вважаю за краще другий підхід, тому що коли ви newпіднімаєте трубу, вам все одно доведеться робити місце. Я вважаю весь @Inject(LOCALE_ID) private locale: stringсинтаксис громіздким.
codeepic

@codeepic Я, певно, не можу сказати, що насправді існує величезна різниця. Якщо ви запитаєте мене, кутовий, мабуть, мав би зробити його провайдером.
csga5000

9

Якщо ви не хочете робити "new myPipe ()", оскільки ви вводите залежності в трубу, ви можете вводити такі компоненти, як постачальник, і використовувати без нових.

Приклад:

// In your component...

import { Component, OnInit } from '@angular/core';
import { myPipe} from './pipes';

@Component({
  selector: 'my-component',
  template: '{{ data }}',
  providers: [ myPipe ]
})
export class MyComponent() implements OnInit {
  data = 'some data';
  constructor(private myPipe: myPipe) {}

  ngOnInit() {
    this.data = this.myPipe.transform(this.data);
  }
}

9

Якщо ви хочете використовувати свою власну трубу у своїх компонентах, ви можете додати її

@Injectable({
  providedIn: 'root'
})

анотація до вашої спеціальної програми. Потім ви можете використовувати його як послугу


чи добре мати providedIn: 'root'всередині нашої труби або в локальному модулі, де використовується труба?
Даніель.V

1
Це залежить від того, де ви використовуєте трубу. Якщо ви використовуєте трубу лише в одному модулі, ви можете вибрати другий варіант. Але якщо ви використовуєте трубу в декількох модулях у вашому додатку, вам слід вибрати перший варіант, який надаєтьсяIn: 'root'
srt

8

Станом на Angular 6 ви можете імпортувати formatDateз @angular/commonутиліти для використання всередині компонентів.

Це було порушено на https://github.com/smdunn/angular/commit/3adeb0d96344c15201f7f1a0fae7e533a408e4ae

Мене можна використовувати як:

import {formatDate} from '@angular/common';
formatDate(new Date(), 'd MMM yy HH:mm', 'en');

Хоча локаль має бути наданий


5

Ви можете використовувати formatDate () для форматування дати в службах або компонентах. синтаксис: -

formatDate(value: string | number | Date, format: string, locale: string, timezone?: string): string

імпортуйте formatDate () із такого загального модуля,

import { formatDate } from '@angular/common';

і просто використовувати його в такому класі,

formatDate(new Date(), 'MMMM dd yyyy', 'en');

Ви також можете використовувати заздалегідь задані параметри формату, надані таким же кутовим,

formatDate(new Date(), 'shortDate', 'en');

Усі інші заздалегідь задані параметри формату можна переглянути тут,

https://angular.io/api/common/DatePipe

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.