Angolare: utilizzare tubi in servizi e componenti


Risposte:


660

Come al solito in Angular, puoi fare affidamento sull'iniezione di dipendenza:

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

class MyService {

  constructor(private datePipe: DatePipe) {}

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

Aggiungi DatePipealla tua lista dei fornitori nel tuo modulo; se ti dimentichi di farlo, otterrai un errore no provider for DatePipe:

providers: [DatePipe,...]

Aggiorna Angular 6 : Angular 6 ora offre praticamente tutte le funzioni di formattazione utilizzate dalle pipe pubblicamente. Ad esempio, ora è possibile utilizzare formatDatedirettamente la funzione.

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

class MyService {

  constructor(@Inject(LOCALE_ID) private locale: string) {}

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

Prima di Angular 5 : tieni presente però che DatePipesi basava sull'API Intl fino alla versione 5, che non è supportata da tutti i browser (controlla la tabella di compatibilità ).

Se si utilizzano versioni angolari precedenti, è necessario aggiungere il Intlpolyfill al progetto per evitare qualsiasi problema. Vedi questa domanda correlata per una risposta più dettagliata.


Quale sarebbe il risultato dell'utilizzo di DatePipe in un browser che non supporta Intl? Esiste un tipo di shim / ployfill disponibile per contrastare la mancanza di supporto?
Conforme a POSIX il

Purtroppo lancerà un errore e romperà la tua app in questo momento. Ci sono problemi aperti sul tracker Github, ma sembra che al momento non ci sia un buon polyfill ...
cexbrayat,

4
Ciò non sembra funzionare con pipe personalizzate che usano a loro volta l'iniezione di dipendenza nel loro costruttore. O mi sbaglio?
Murray Smith

1
@JayChase è in "angular2 / common".
valter.santos.matos

5
@JayChase importa e aggiungi le sezioni del provider di componenti: `` import {DatePipe} da '@ angular / common'; @Component ({... provider: [..., DatePipe]}) `` `
alx lark

74

Questa risposta è ora obsoleta

consiglia di utilizzare l'approccio DI da altre risposte anziché questo approccio

Risposta originale:

Dovresti essere in grado di utilizzare direttamente la classe

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

Per esempio

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

2
Quando si utilizza il Datecostruttore javascript , si 0basano i mesi . Quindi 0è gennaio ed 1è febbraio. Manca correttoy
SnareChops

24
Nel caso in cui aiuti qualcun altro, la pipe della data viene importata da 'angular2 / common'.
Conforme a POSIX il

1
Lo snippet di codice non viene compilato .... error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'string'. on linevar formatted = new DatePipe().transform(raw, ['yyyy-MM-dd']);
Paul Gorbas,

10
Ora rilasciato Angular v2.0.0 e puoi iniettare questa pipa. Innanzitutto, aggiungi a NgModule:, @NgModule({ providers:[DatePipe] })poi nella tua classe, importa e inietta constructor( private datePipe: DatePipe ){}
ktretyak,

2
nel frattempo Angular2 DatePipe prevede Locale_ID come argomento del costruttore. Quindi, se provi a usarlo direttamente, dovresti fornire una correzione Locale_ID e quindi non richiederà più le app Locale_ID. Ecco perché NON consiglierei di andare in quel modo.
E. Hein,

17

Sì, è possibile utilizzando una semplice pipe personalizzata. Il vantaggio di utilizzare la pipe personalizzata è se in futuro avremo bisogno di aggiornare il formato della data, possiamo andare e aggiornare un singolo 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 }}

Puoi sempre usare questa pipa ovunque, componente, servizi ecc

Per esempio

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

Non dimenticare di importare dipendenze.

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

Esempi di tubi personalizzati e maggiori informazioni


1
Questo non risponde alla domanda su come usare le pipe in un componente o servizio.
Conformità POSIX

2
Rimuoverò il mio downvote se aggiornerai la tua risposta per non includere informazioni su come creare pipe. La domanda non ha nulla a che fare con come crearli.
Conformità POSIX

2
Conformità a POSIX @ Come ho già detto nella mia risposta, può riutilizzare e aggiornare molto facilmente utilizzando la pipe personalizzata. Potrebbe aiutare a qualcun altro. I voti sono secondari.
Prashobh,

1
Questo è un punto giusto, anche se penso ancora che abbia senso almeno avere la parte che risponde prima a questa domanda specifica. Rimozione del voto contrario. Grazie per la risposta e la risposta.
Conforme a POSIX il

1
Perché hai hardcode "en-US"? Non dovresti iniettare in qualche modo?
Gherman,

15

Altre risposte non funzionano in Angular 5?

Ho ricevuto un errore perché DatePipe non è un provider, quindi non può essere iniettato. Una soluzione è inserirla come provider nel modulo dell'app, ma la mia soluzione preferita è stata istanziarla.

Crea un'istanza dove necessario:

Ho guardato il codice sorgente di DatePipe per vedere come ha ottenuto la localizzazione: https://github.com/angular/angular/blob/5.2.5/packages/common/src/pipes/date_pipe.ts#L15-L174

Volevo usarlo all'interno di una pipe, quindi il mio esempio è all'interno di un'altra 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')
    }
}

La chiave qui è importare Inject e LOCALE_ID dal core di angular, quindi iniettarlo in modo da poterlo dare al DatePipe per istanziarlo correttamente.

Trasforma DatePipe in un provider

Nel modulo dell'app puoi anche aggiungere DatePipe all'array dei tuoi provider in questo modo:

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

@NgModule({
    providers: [
        DatePipe
    ]
})

Ora puoi semplicemente iniettarlo nel tuo costruttore dove necessario (come nella risposta di cexbrayat).

Sommario:

Entrambe le soluzioni hanno funzionato, non so quale angolare considererebbe la maggior parte "corretta", ma ho scelto di crearne un'istanza manualmente poiché angular non ha fornito datepipe come provider stesso.


3
Puoi renderlo anche un fornitore per componente
Jimmy Kane,

Grazie, la tua risposta è la più esaustiva. Sto cercando alcune risorse sulle differenze tra l'istanza della pipe con la nuova o la dipendenza iniettandola direttamente e aggiungendola ai provider e non riesco a trovare nulla. Preferisco il secondo approccio, perché quando si avvia newla pipe, è ancora necessario DI impostazioni internazionali. Trovo @Inject(LOCALE_ID) private locale: stringingombrante l'intera sintassi.
codeepic

@codeepic Probabilmente non direi che c'è davvero una grande differenza. Se me lo chiedi, probabilmente Angular avrebbe dovuto renderlo un fornitore.
csga5000,

9

Se non vuoi fare 'new myPipe ()' perché stai iniettando dipendenze su pipe, puoi iniettare componenti come provider e utilizzarli senza nuovi.

Esempio:

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

Se si desidera utilizzare la pipa personalizzata nei componenti, è possibile aggiungere

@Injectable({
  providedIn: 'root'
})

annotazione per la tua pipe personalizzata. Quindi, puoi usarlo come servizio


è bello avere providedIn: 'root'dentro la nostra pipa o fornito in un modulo locale dove viene usata la pipa?
Daniel.V,

1
Dipende da dove usi la pipa. Se si utilizza la pipe in un solo modulo, è possibile selezionare la seconda opzione. Ma se usi la pipe in diversi moduli nella tua app, dovresti selezionare la prima opzione che viene fornitaIn: 'root'
srt


5

È possibile utilizzare formatDate () per formattare la data in servizi o componenti ts. sintassi:-

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

importa il formatDate () dal modulo comune in questo modo,

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

e usalo in classe come questo,

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

Puoi anche utilizzare le opzioni di formato predefinite fornite da Angular in questo modo,

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

Puoi vedere tutte le altre opzioni di formato predefinite qui,

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.