Angular-サービスとコンポーネントでパイプを使用する


331

AngularJSでは、次のような構文を使用して、サービスおよびコントローラー内でフィルター(パイプ)を使用できます。

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

Angularのこのようなサービス/コンポーネントでパイプを使用することは可能ですか?


1
Angular 8の場合組み込みパイプとカスタムパイプに関するこのチュートリアルを確認してください freakyjolly.com/angular-8-pipes-all-type-of-pipes-with-examples
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バージョン5まではIntl APIに依存していたため、すべてのブラウザーでサポートされているわけではありません(互換性の表を確認してください)。

古いAngularバージョンを使用している場合はIntl、プロジェクトにポリフィルを追加して問題を回避する必要があります。より詳細な回答については、この関連質問を参照してください。


IntlをサポートしていないブラウザーでDatePipeを使用した結果はどうなりますか?サポートの不足に対処するために利用できるシム/プロイフィルの種類はありますか?
POSIX準拠、

それは悲しいことにエラーを投げ、今あなたのアプリを壊します。Githubトラッカーで未解決の問題がありますが、現在、適切なポリフィルがないようです...
cexbrayat

4
これは、コンストラクターで依存関係注入を使用するカスタムパイプでは機能しないようです。それとも私は間違っていますか?
マレースミス

1
@JayChaseは「angular2 / common」にあります。
valter.santos.matos

5
@JayChaseインポートおよびコンポーネントプロバイダーセクションの追加: `` `import {DatePipe} from '@ 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
JavaScript Dateコンストラクターを使用する場合、月は基準0になります。だから、01月で、12月です。行方不明の修正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']);
Paul Gorbas

10
Angular v2.0.0がリリースされました。このパイプを挿入できます。最初にNgModule:に追加し@NgModule({ providers:[DatePipe] })、次にクラスでインポートして注入します constructor( private datePipe: DatePipe ){}
ktretyak

2
一方、Angular2 DatePipeはコンストラクタ引数としてLocale_IDを期待します。したがって、直接使用する場合は、修正Locale_IDを提供する必要があるため、アプリのLocale_IDを使用できなくなります。そういうわけで私はそのように行くことをお勧めしません。
E.ハイン

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準拠私の回答で述べたように、カスタムパイプを使用することで、非常に簡単に再利用および更新できます。それは他の誰かに完全に役立つかもしれません。投票は二次的です。
Prashobh

1
少なくともこの特定の質問に最初に答える部分があることが理にかなっているとは思いますが、それは公平な点です。反対票を取り除きます。回答と返信をありがとう。
POSIX準拠

1
なぜ「en-US」をハードコーディングしたのですか?なんとか注入してはいけませんか?
ガーマン

15

Angular 5では他の回答が機能しませんか?

DatePipeはプロバイダーではないため、注入できないため、エラーが発生しました。1つの解決策は、それをプロバイダーとしてアプリモジュールに配置することですが、私の好ましい解決策は、それをインスタンス化することでした。

必要に応じてインスタンス化します。

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

ここで重要なのは、AngleのコアからInjectとLOCALE_IDをインポートし、それを注入して、DatePipeに渡して適切にインスタンス化できるようにすることです。

DatePipeをプロバイダーにする

アプリモジュールで、次のようにプロバイダー配列にDatePipeを追加することもできます。

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

@NgModule({
    providers: [
        DatePipe
    ]
})

これで、必要に応じてコンストラクターに注入することができます(cexbrayatの回答のように)。

概要:

どちらの解決策も機能しましたが、どのAngularが最も「正しい」と見なすかはわかりませんが、Angleはプロバイダー自体として日付パイプを提供していなかったため、手動でインスタンス化することを選択しました。


3
コンポーネントごとのプロバイダーにすることもできます
Jimmy Kane

ありがとう、あなたの答えは最も徹底的です。新規または依存関係を使用してパイプをインスタンス化することと、パイプをプロバイダーに直接追加することとの違いに関するリソースを探していますが、何も見つかりません。私は2番目のアプローチを好みnewます。パイプを上回ったときに、ロケールをDIする必要があるからです。@Inject(LOCALE_ID) private locale: string構文全体が面倒です。
codeepic 2018

@codeepic本当に大きな違いがあるとはおそらく言えないでしょう。あなたが私に尋ねるならば、angularはおそらくそれをプロバイダーにすべきでした。
csga5000 2018

9

依存関係をパイプに注入するために 'new myPipe()'を実行したくない場合は、プロバイダーなどのコンポーネントを注入し、newなしで使用できます。

例:

// 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'私たちのパイプの中に持っているのがいいですか、それともパイプが使用されているローカルモジュールで提供されているのですか?
Daniel.V

1
パイプを使用する場所によって異なります。1つのモジュールのみでパイプを使用する場合は、2番目のオプションを選択できます。ただし、アプリのいくつかのモジュールでパイプを使用する場合は、最初に提供されているオプションを選択する必要があります
。In


5

formatDate()を使用して、サービスまたはコンポーネントtsの日付をフォーマットできます。構文:-

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

このようにangularによって提供される事前定義されたフォーマットオプションを使用することもできます、

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

他のすべての定義済みフォーマットオプションはここで確認できます。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.