parametros - Angular: use tuberías en servicios y componentes
pasar datos entre componentes angular 5 (8)
¿Otras respuestas no funcionan en angular 5?
Recibí un error porque DatePipe no es un proveedor, por lo que no se puede inyectar. Una solución es incluirlo como proveedor en el módulo de la aplicación, pero mi solución preferida era crear una instancia.
Instalarlo donde sea necesario:
Miré el código fuente de DatePipe para ver cómo obtuvo 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 dárselo a DatePipe para crear una instancia adecuada.
Hacer de DatePipe un proveedor
En el módulo de su aplicación, también podría agregar DatePipe a su matriz de proveedores de esta manera:
import { DatePipe } from ''@angular/common'';
@NgModule({
providers: [
DatePipe
]
})
Ahora puede inyectarlo en su constructor donde sea necesario (como en la respuesta de cexbrayat).
Resumen:
Cualquiera de las soluciones funcionó, no sé cuál angular consideraría más "correcto", pero elegí crear una instancia manual ya que angular no proporcionó datepipe como proveedor.
En AngularJS, puedo usar filtros (tuberías) 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?
Esta respuesta ahora está desactualizada
recomiendo usar el enfoque DI de otras respuestas en lugar de este enfoque
Respuesta original:
Deberías 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'');
A partir de Angular 6, puede importar
formatDate
desde
@angular/common
utilidad
@angular/common
para usar dentro de los componentes.
Se introdujo en https://github.com/smdunn/angular/commit/3adeb0d96344c15201f7f1a0fae7e533a408e4ae
Puedo ser usado como:
import {formatDate} from ''@angular/common'';
formatDate(new Date(), ''d MMM yy HH:mm'', ''en'');
Aunque el local tiene que ser suministrado
Como es habitual en Angular, puede confiar en la inyección de dependencia:
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, recibirá un error de
no provider for DatePipe
:
providers: [DatePipe,...]
Actualización de Angular 6
: Angular 6 ahora ofrece prácticamente todas las funciones de formato utilizadas públicamente por las canalizaciones.
Por ejemplo, ahora puede usar la función
formatDate
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
: Tenga en cuenta que
DatePipe
confiaba 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 polyfill
Intl
a su proyecto para evitar cualquier problema.
Consulte esta
pregunta relacionada
para obtener una respuesta más detallada.
Puede usar formatDate () para formatear la fecha en servicios o componentes ts. sintaxis:-
formatDate(value: string | number | Date, format: string, locale: string, timezone?: string): string
importa el formatDate () desde un módulo común como este,
import { formatDate } from ''@angular/common'';
y solo utilízalo en la clase como esta,
formatDate(new Date(), ''MMMM dd yyyy'', ''en'');
También puede usar las opciones de formato predefinidas proporcionadas por angular de esta manera,
formatDate(new Date(), ''shortDate'', ''en'');
Puede ver todas las demás opciones de formato predefinidas aquí,
Sí, es posible mediante el uso de una tubería personalizada simple. La ventaja de usar una tubería personalizada es que si necesitamos actualizar el formato de fecha en el futuro, podemos ir y actualizar 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 olvides importar dependencias.
import { Component } from ''@angular/core'';
import {dateFormatPipe} from ''./pipes''
Si desea utilizar su tubería personalizada en sus componentes, puede agregar
@Injectable({
providedIn: ''root''
})
anotación a su tubería personalizada. Entonces, puedes usarlo como un servicio
Si no desea hacer ''new myPipe ()'' porque está inyectando dependencias a la tubería, puede inyectar componentes como proveedor y usar sin nuevos.
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);
}
}