Angular-在服务和组件中使用管道


Answers:


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版本,则应将Intlpolyfill 添加到项目中以避免任何问题。请参阅此相关问题以获取更详细的答案。


在不支持Intl的浏览器中使用DatePipe会产生什么结果?是否可以使用任何类型的填充/填充填充物来应对缺乏支持的情况?
符合POSIX要求的

不幸的是,它会引发错误并立即中断您的应用程序。Github跟踪器上存在一些问题,但看来目前还没有很好的
polyfill

4
这对于自定义管道似乎不起作用,自定义管道本身在其构造函数中使用依赖项注入。还是我弄错了?
默里·史密斯

1
@JayChase位于“ angular2 / common”中。
valter.santos.matos

5
@JayChase导入并添加组件提供程序部分:```从'@ angular / common'导入{DatePipe}; @Component({... provider:[...,DatePipe]))```
alk 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基础。所以0是一月和1是2月。更正了失误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 '16

10
现在发布了Angular v2.0.0,您可以注入该管道。首先,添加到NgModule:,@NgModule({ providers:[DatePipe] })然后在您的课程中导入和注入 constructor( private datePipe: DatePipe ){}
ktretyak

2
同时Angular2 DatePipe需要Locale_ID作为构造函数参数。因此,如果您尝试直接使用它,则必须提供修复程序Locale_ID,因此它将不再使用应用程序Locale_ID。这就是为什么我不建议您那样走的原因。
E. Hein

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”?你不应该以某种方式注入吗?
Gherman

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

此处的关键是从angular的核心导入Inject和LOCALE_ID,然后进行注入,以便将其提供给DatePipe以正确实例化它。

使DatePipe成为提供程序

在您的应用模块中,您还可以将DatePipe添加到您的provider数组中,如下所示:

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

@NgModule({
    providers: [
        DatePipe
    ]
})

现在,您可以将它注入所需的构造函数中(如cexbrayat的答案)。

摘要:

无论哪种解决方案都有效,我不知道哪个角度会认为最“正确”,但我选择手动实例化它,因为angular本身并未提供日期管道。


2
您也可以使它成为每个组件提供者
Jimmy Kane

谢谢,您的回答是最详尽的。我正在寻找一些有关在使用新实例或依赖实例直接实例化管道并将其添加到提供程序而找不到任何内容之间的区别的资源。我更喜欢第二种方法,因为当您new使用管道时,您仍然必须DI语言环境。我觉得整个@Inject(LOCALE_ID) private locale: string语法很麻烦。
codeepic '18

@codeepic我可能不会说真的有很大的不同。如果您问我,angular可能应该使它成为提供程序。
csga5000 '18

9

如果要在组件中使用自定义管道,则可以添加

@Injectable({
  providedIn: 'root'
})

您的自定义管道的注释。然后,您可以将其用作服务


这是件好事,providedIn: 'root'我们的管道内或者在使用管道局部模块中提供?
Daniel.V

1
这取决于您在何处使用管道。如果仅在一个模块中使用管道,则可以选择第二个选项。但是,如果您在应用程序的多个模块中使用管道,则应选择提供的第一个选项:'
root'– srt

8

如果因为要注入要依赖的管道而不想执行“ new myPipe()”,则可以注入诸如provider之类的组件,而无需使用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);
  }
}


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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.