Angular - Tubos de uso en servicios y componentes


En AngularJS, puedo usar filtros (pipes) dentro de servicios y controladores usando una sintaxis similar a esta:

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

¿Es posible usar tuberías en servicios/componentes como este en Angular?

 207
Author: Lazar Ljubenović, 2016-02-02

6 answers

Como es habitual en Angular, puede confiar en la inyección de dependencias:

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

class MyService {

  constructor(private datePipe: DatePipe) {}

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

Agregue DatePipe a su lista de proveedores en su módulo; si olvida hacer esto, obtendrá un error no provider for DatePipe:

providers: [DatePipe,...]

Actualización Angular 6 : Angular 6 ahora ofrece prácticamente todas las funciones de formato utilizadas por las tuberías públicamente. Por ejemplo, ahora puede utilizar el formatDate funciona directamente.

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

class MyService {

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

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

Antes de Angular 5 : Se advierte sin embargo que el DatePipe estaba confiando en la API Intl hasta la versión 5, que no es compatible con todos los navegadores (consulte la tabla de compatibilidad ).

Si está utilizando versiones anteriores de Angular, debe agregar el Intl polyfill a su proyecto para evitar cualquier problema. Vea esta pregunta relacionada para una respuesta más detallada.

 407
Author: cexbrayat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-12 16:58:01

Esta respuesta ahora está desactualizada

Recomendar el uso del enfoque DI

Debería poder usar la clase directamente

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

Por ejemplo

var raw = new Date(2015, 1, 12);
var formatted = new DatePipe().transform(raw, 'yyyy-MM-dd');
expect(formatted).toEqual('2015-02-12');
 63
Author: SnareChops,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-17 19:05:24

Sí es posible mediante el uso de un tubo personalizado simple. La ventaja de usar tubería personalizada es que si necesitamos actualizar el formato de fecha en el futuro, vaya y actualice un solo archivo.

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

Siempre puede usar esta tubería en cualquier lugar , componente, servicios, etc

Por ejemplo

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

No se olvidó de importar dependencias.

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

Ejemplos de tubos personalizados y más información

 10
Author: Prashobh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-07 10:04:14

Otras respuestas no funcionan en angular 5?

Tengo un error porque DatePipe no es un proveedor, por lo que no se puede inyectar. Una solución es ponerlo como proveedor en su módulo de aplicación, pero mi solución preferida era instanciarlo.

Instanciarlo donde sea necesario:

Miré el código fuente de DatePipe para ver cómo obtenía la configuración regional: https://github.com/angular/angular/blob/5.2.5/packages/common/src/pipes/date_pipe.ts#L15-L174

Quería usarlo dentro de una tubería, así que mi ejemplo está dentro de otra tubería:

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 clave aquí es importar Inject, y LOCALE_ID desde el núcleo de angular, y luego inyectarlo para que pueda darlo al DatePipe para instanciarlo correctamente.

Hacer de DatePipe un proveedor

En su módulo de aplicación también podría agregar DatePipe a su matriz de proveedores de la siguiente manera:

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

@NgModule({
    providers: [
        DatePipe
    ]
})

Ahora solo puede inyectarlo en su constructor donde sea necesario (como en el caso de cexbrayat respuesta).

Resumen:

Cualquiera de las dos soluciones funcionó, no se cuál de ellas consideraría más "correcta" pero elegí instanciarla manualmente ya que angular no proporcionó datepipe como proveedor.

 7
Author: csga5000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 21:40:06

A partir de Angular 6 puede importar formatDate desde la utilidad @angular/common para usar dentro de los componentes.

Fue intruido en https://github.com/smdunn/angular/commit/3adeb0d96344c15201f7f1a0fae7e533a408e4ae

Puedo ser utilizado como:

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

Aunque la configuración regional tiene que ser suministrada

 5
Author: Jimmy Kane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-14 11:02:51

Si no quieres hacer 'new myPipe()' porque estás inyectando dependencias a la tubería, puedes inyectar componentes como provider y usar sin nuevo.

Ejemplo:

// 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);
  }
}
 4
Author: andy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-20 08:15:37