web-dev-qa-db-fra.com

Angular - Utiliser des canaux dans des services et des composants

Dans AngularJS, je peux utiliser des filtres (tuyaux) dans des services et des contrôleurs en utilisant une syntaxe similaire à celle-ci:

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

Est-il possible d'utiliser des tuyaux dans des services/composants comme celui-ci dans Angular?

287
POSIX-compliant

Comme d'habitude dans Angular, vous pouvez compter sur l'injection de dépendance:

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

class MyService {

  constructor(private datePipe: DatePipe) {}

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

Ajoutez DatePipe à la liste de vos fournisseurs dans votre module; Si vous oubliez de le faire, vous obtiendrez une erreur no provider for DatePipe:

providers: [DatePipe,...]

Mise à jour Angular 6 : Angular 6 offre désormais à peu près toutes les fonctions de formatage utilisées publiquement par les canaux. Par exemple, vous pouvez maintenant utiliser directement la fonction 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);
  }
}

Avant Angular 5 : soyez averti que le DatePipe s’appuyait sur l’API Intl jusqu’à la version 5, qui n’est pas prise en charge par tous. navigateurs (consultez le tableau de compatibilité ).

Si vous utilisez d'anciennes versions de Angular, vous devez ajouter le fichier Intl à votre projet pour éviter tout problème. Voir ceci question connexe pour une réponse plus détaillée.

567
cexbrayat

Cette réponse est maintenant obsolète

recommande d'utiliser l'approche DI à partir d'autres réponses plutôt que cette approche

Réponse originale:

Vous devriez pouvoir utiliser la classe directement

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

Par exemple

var raw = new Date(2015, 1, 12);
var formatted = new DatePipe().transform(raw, 'yyyy-MM-dd');
expect(formatted).toEqual('2015-02-12');
69
SnareChops

Oui, c'est possible en utilisant un simple tuyau personnalisé. L'avantage d'utiliser un canal personnalisé est que si nous devons mettre à jour le format de date à l'avenir, nous pouvons aller mettre à jour un seul fichier.

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

Vous pouvez toujours utiliser ce tuyau n'importe où, composant, services, etc.

Par exemple

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

N'oubliez pas d'importer des dépendances.

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

exemples de tuyaux personnalisés et informations supplémentaires

12
Prashobh

Les autres réponses ne fonctionnent pas dans angular 5?

J'ai eu une erreur parce que DatePipe n'est pas un fournisseur, il ne peut donc pas être injecté. Une solution consiste à le définir en tant que fournisseur dans votre module d'application, mais ma solution préférée consistait à l'instancier.

Instanciez-le si nécessaire:

J'ai consulté le code source de DatePipe pour voir comment il obtenait les paramètres régionaux: https://github.com/angular/angular/blob/5.2.5/packages/common/src/pipes/date_pipe.ts#L15- L174

Je voulais l'utiliser dans un tuyau, mon exemple est donc dans un autre tuyau:

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

La clé ici est d'importer Inject et LOCALE_ID depuis le noyau d'angular, puis de l'injecter afin que vous puissiez le donner à DatePipe pour l'instancier correctement.

Faire de DatePipe un fournisseur

Dans votre module d'application, vous pouvez également ajouter DatePipe à votre tableau de fournisseurs comme ceci:

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

@NgModule({
    providers: [
        DatePipe
    ]
})

Maintenant, vous pouvez simplement l'avoir injecté dans votre constructeur si nécessaire (comme dans la réponse de cexbrayat).

Sommaire:

Quelle que soit la solution choisie, je ne sais pas lequel angular considérerait le plus comme "correct", mais j'ai choisi de l'instancier manuellement car angular ne fournissait pas le programme Datepipe en tant que fournisseur.

11
csga5000

Si vous ne voulez pas créer "new myPipe ()" parce que vous injectez des dépendances dans un tuyau, vous pouvez injecter un composant tel que provider et l'utiliser sans nouveau.

Exemple:

// 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
andy

À partir de Angular 6, vous pouvez importer l'utilitaire formatDate from @angular/common à utiliser à l'intérieur des composants.

Il a été intruduit par https://github.com/smdunn/angular/commit/3adeb0d96344c15201f7f1a0fae7e533a408e4ae

Je peux être utilisé comme:

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

Bien que les paramètres régionaux doivent être fournis

6
Jimmy Kane

Si vous souhaitez utiliser votre canal personnalisé dans vos composants, vous pouvez ajouter

@Injectable({
  providedIn: 'root'
})

annotation à votre pipe personnalisée. Ensuite, vous pouvez l'utiliser comme un service

6
srt

Vous pouvez utiliser formatDate () pour formater la date dans les services ou les composants ts. syntaxe:-

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

importer le formatDate () du module commun comme ceci,

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

et juste l'utiliser dans la classe comme ça,

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

Vous pouvez également utiliser les options de format prédéfinies fournies par angular comme ceci,

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

Vous pouvez voir toutes les autres options de format prédéfinies ici,

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

2
Sksaif Uddin