Angular - использовать трубы в сервисах и компонентах

В AngularJS я могу использовать фильтры (трубы) внутри служб и контроллеров, используя синтаксис, подобный этому:

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

Можно ли использовать каналы в сервисах/компонентах, например, в Angular?

Ответ 1

Как обычно в Angular, вы можете полагаться на инъекцию зависимостей:

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

  constructor(private datePipe: DatePipe) {}

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

Добавить DatePipe в список ваших поставщиков в вашем модуле; если вы забудете сделать это, вы получите сообщение об ошибке no provider for DatePipe:

providers: [DatePipe,...] 

Следует помнить, что DatePipe полагался на Intl API до версии 5, которая не поддерживается всеми браузерами (проверьте таблицу совместимости ).

Если вы используете старые версии Angular, вы должны добавить Intl polyfill в свой проект, чтобы избежать каких-либо проблем. См. Этот вопрос для получения более подробного ответа.

Ответ 2

Этот ответ устарел

рекомендуется использовать подход 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');

Ответ 3

Да, это возможно, используя простой пользовательский канал. Преимущество использования настраиваемого канала заключается в том, что нам нужно обновить формат даты в будущем, перейти и обновить один файл.

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'

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

Ответ 4

Другие ответы не работают в angular 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 из ядра angular, а затем ввод данных, чтобы вы могли передать его в DatePipe для его правильного создания.

Сделать DatePipe провайдером

В вашем модуле приложения вы также можете добавить DatePipe в свой массив поставщиков следующим образом:

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

@NgModule({
    providers: [
        DatePipe
    ]
})

Теперь вы можете просто ввести его в свой конструктор там, где это необходимо (например, в ответ cexprayat).

Резюме:

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

Ответ 5

Если вы не хотите делать "новый myPipe()", потому что вы вставляете зависимости в pipe, вы можете вводить их в качестве поставщика и использовать без новых.

Пример:

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

Ответ 6

Как и в случае с 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');

Хотя языковой стандарт должен быть предоставлен