Angular - Use pipes in services and components

前端 未结 8 1445
南笙
南笙 2020-11-22 09:42

In AngularJS, I am able to use filters (pipes) inside of services and controllers using syntax similar to this:

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


        
相关标签:
8条回答
  • 2020-11-22 10:12

    If you want to use your custom pipe in your components, you can add

    @Injectable({
      providedIn: 'root'
    })
    

    annotation to your custom pipe. Then, you can use it as a service

    0 讨论(0)
  • 2020-11-22 10:14

    You can use formatDate() to format the date in services or component ts. syntax:-

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

    import the formatDate() from common module like this,

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

    and just use it in the class like this ,

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

    You can also use the predefined format options provided by angular like this ,

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

    You can see all other predefined format options here ,

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

    0 讨论(0)
  • 2020-11-22 10:22

    Other answers don't work in angular 5?

    I got an error because DatePipe is not a provider, so it cannot be injected. One solution is to put it as a provider in your app module but my preferred solution was to instantiate it.

    Instantiate it where needed:

    I looked at DatePipe's source code to see how it got the locale: https://github.com/angular/angular/blob/5.2.5/packages/common/src/pipes/date_pipe.ts#L15-L174

    I wanted to use it within a pipe, so my example is within another pipe:

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

    The key here is importing Inject, and LOCALE_ID from angular's core, and then injecting that so you can give it to the DatePipe to instantiate it properly.

    Make DatePipe a provider

    In your app module you could also add DatePipe to your providers array like this:

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

    Now you can just have it injected in your constructor where needed (like in cexbrayat's answer).

    Summary:

    Either solution worked, I don't know which one angular would consider most "correct" but I chose to instantiate it manually since angular didn't provide datepipe as a provider itself.

    0 讨论(0)
  • 2020-11-22 10:23

    This answer is now outdated

    recommend using DI approach from other answers instead of this approach

    Original answer:

    You should be able to use the class directly

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

    For instance

    var raw = new Date(2015, 1, 12);
    var formatted = new DatePipe().transform(raw, 'yyyy-MM-dd');
    expect(formatted).toEqual('2015-02-12');
    
    0 讨论(0)
  • 2020-11-22 10:25

    Yes, it is possible by using a simple custom pipe. Advantage of using custom pipe is if we need to update the date format in future, we can go and update a single file.

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

    You can always use this pipe anywhere , component, services etc

    For example

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

    Dont forget to import dependencies.

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

    Custom Pipe examples and more info

    0 讨论(0)
  • As usual in Angular, you can rely on dependency injection:

    import { DatePipe } from '@angular/common';
    
    class MyService {
    
      constructor(private datePipe: DatePipe) {}
    
      transformDate(date) {
        return this.datePipe.transform(date, 'yyyy-MM-dd');
      }
    }
    

    Add DatePipe to your providers list in your module; if you forget to do this you'll get an error no provider for DatePipe:

    providers: [DatePipe,...]
    

    Update Angular 6: Angular 6 now offers pretty much every formatting functions used by the pipes publicly. For example, you can now use the formatDate function directly.

    import { formatDate } from '@angular/common';
    
    class MyService {
    
      constructor(@Inject(LOCALE_ID) private locale: string) {}
    
      transformDate(date) {
        return formatDate(date, 'yyyy-MM-dd', this.locale);
      }
    }
    

    Before Angular 5: Be warned though that the DatePipe was relying on the Intl API until version 5, which is not supported by all browsers (check the compatibility table).

    If you're using older Angular versions, you should add the Intl polyfill to your project to avoid any problem. See this related question for a more detailed answer.

    0 讨论(0)
提交回复
热议问题