【问题标题】:Angular - Use pipes in services and componentsAngular - 在服务和组件中使用管道
【发布时间】:2016-05-10 17:56:35
【问题描述】:

在 AngularJS 中,我可以使用类似于以下的语法在服务和控制器中使用过滤器(管道):

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

是否可以在 Angular 这样的服务/组件中使用管道?

【问题讨论】:

    标签: angular


    【解决方案1】:

    像往常一样在 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,但并非所有浏览器都支持该 API(请查看 compatibility table)。

    如果您使用的是较旧的 Angular 版本,则应将 Intl polyfill 添加到您的项目中以避免任何问题。 请参阅此related question 以获得更详细的答案。

    【讨论】:

    • 在不支持 Intl 的浏览器中使用 DatePipe 会有什么结果?是否有任何类型的 shim/ployfill 可用于解决缺乏支持的问题?
    • 遗憾的是,它会立即抛出错误并破坏您的应用程序。 Github tracker 上打开了一些问题,但看起来目前没有好的 polyfill...
    • 这似乎不适用于自定义管道,这些管道本身在构造函数中使用依赖注入。还是我弄错了?
    • @JayChase 在“angular2/common”中。
    • @JayChase 导入并添加组件提供程序部分:``` import {DatePipe} from '@angular/common'; @Component({ ... 提供者: [ ..., DatePipe ] }) ```
    【解决方案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');
    

    【讨论】:

    • 当使用 javascript Date 构造函数时,月份是基于 0 的。所以0 是一月,1 是二月。更正了缺失的y
    • 如果对其他人有帮助,日期管道是从 'angular2/common' 导入的。
    • 代码 sn-p 无法编译......error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'string'.在线var formatted = new DatePipe().transform(raw, ['yyyy-MM-dd']);
    • 现在发布了Angular v2.0.0,你可以注入这个管道。首先,添加到 NgModule:@NgModule({ providers:[DatePipe] }),然后在你的类中,导入并注入 constructor( private datePipe: DatePipe ){}
    • 同时 Angular2 DatePipe 期望 Locale_ID 作为构造函数参数。因此,如果您尝试直接使用它,则必须提供一个修复 Locale_ID,因此它不再需要应用程序 Locale_ID。这就是为什么我不建议这样做。
    【解决方案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')
              }
          }
      

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

      使 DatePipe 成为提供者

      在您的应用模块中,您还可以像这样将 DatePipe 添加到您的提供程序数组中:

          import { DatePipe } from '@angular/common';
      
          @NgModule({
              providers: [
                  DatePipe
              ]
          })
      

      现在你可以在需要的地方将它注入你的构造函数中(就像在 cexbrayat 的回答中一样)。

      总结:

      这两种解决方案都有效,我不知道哪个 Angular 会认为最“正确”,但我选择手动实例化它,因为 Angular 本身没有提供日期管道。

      【讨论】:

      • 您也可以将其设为每个组件的提供者
      • 谢谢,您的回答是最详尽的。我正在寻找一些资源,了解使用 new 或依赖项直接注入管道并将其添加到提供程序之间的差异,但找不到任何东西。我更喜欢第二种方法,因为当您newup 管道时,您仍然需要 DI 语言环境。我发现整个 @Inject(LOCALE_ID) private locale: string 语法很麻烦。
      • @codeepic 我可能不会说真的有很大的不同。如果你问我,Angular 可能应该让它成为提供者。
      【解决方案5】:

      如果你不想做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);
            }
          }
      

      【讨论】:

      • 不错但是我认为它只回答了一半的问题,因为这里的所有答案都讨论了带有服务的管道,并且没有提到可以直接与模板一起使用的角度提供的管道,例如 {{欢迎来到角 |小写}}等你可以提到它;)
      【解决方案6】:

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

      @Injectable({
        providedIn: 'root'
      })
      

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

      【讨论】:

      • 在我们的管道中使用providedIn: 'root' 好还是在使用管道的本地模块中提供?
      • 这取决于您使用管道的位置。如果您只在一个模块中使用管道,那么您可以选择第二个选项。但是如果您在应用程序的多个模块中使用管道,则应选择提供的第一个选项:'root'
      【解决方案7】:

      从 Angular 6 开始,您可以从 @angular/common 实用程序导入 formatDate 以在组件内部使用。

      https://github.com/smdunn/angular/commit/3adeb0d96344c15201f7f1a0fae7e533a408e4ae引入

      我可以用作:

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

      虽然必须提供语言环境

      【讨论】:

        【解决方案8】:

        您可以使用 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

        【讨论】:

          猜你喜欢
          • 2019-07-04
          • 2019-01-14
          • 2016-08-17
          • 1970-01-01
          • 1970-01-01
          • 2017-12-07
          • 2022-12-21
          • 1970-01-01
          相关资源
          最近更新 更多