yyyy spanish new language example date angular pipe

spanish - format date angular 6



Angular 2 "hace tiempo" tubo (7)

Estoy tratando de crear un conducto ''tiempo atrás'' para mi aplicación Angular 2.

Debe transformar una fecha en una cadena como ''hace 5 minutos'' o ''hace 60 segundos''. Funciona bien hasta ahora, pero no se actualiza después del primer cálculo. Si la fecha dada es, por ejemplo, hace 5 segundos, muestra "hace 5 segundos" pero nunca cambia después de eso.

Ya he intentado establecer el valor "puro" de las tuberías en falso, pero eso no ayudó.

Aquí está mi código:

import {Pipe, PipeTransform} from ''angular2/core''; @Pipe({ name: ''messageTime'', pure: false }) export class MessageTimePipe implements PipeTransform { transform(value: Date, []): string { var result: string; // current time let now = new Date().getTime(); // time since message was sent in seconds let delta = (now - value.getTime()) / 1000; // format string if (delta < 10) { result = ''jetzt''; } else if (delta < 60) { // sent in last minute result = ''vor '' + Math.floor(delta) + '' Sekunden''; } else if (delta < 3600) { // sent in last hour result = ''vor '' + Math.floor(delta / 60) + '' Minuten''; } else if (delta < 86400) { // sent on last day result = ''vor '' + Math.floor(delta / 3600) + '' Stunden''; } else { // sent more than one day ago result = ''vor '' + Math.floor(delta / 86400) + '' Tagen''; } return result; } }

Estoy usando el filtro de esta manera:

Mecanografiado:

import {Component, Input} from ''angular2/core''; import {MessageTimePipe} from ''../../pipes/message-time.pipe''; @Component({ selector: ''message-item'', pipes: [MessageTimePipe], templateUrl: ''build/components/message-item/message-item.component.html'' }) export class MessageItemComponent { @Input() message: JSON; date: Date; ngOnInit() { this.date = new Date(2016, 3, 16, 12, 49, 10); } }

HTML:

<p class="time"> {{ date | messageTime }} </p>



Acabo de usar esto:

https://www.npmjs.com/package/time-ago-pipe

npm install time-ago-pipe --save

Luego en el @NgModule quieres usarlo en:

import {TimeAgoPipe} from ''time-ago-pipe @NgModule({ imports: [... etc ...], declarations: [AppComponent, ...etc..., TimeAgoPipe], bootstrap: [AppComponent] })

Y en la plantilla:

<span>{{your_date | timeAgo}}</span>

No reinvente la rueda, a menos que planee aprender más sobre las ruedas.


Basándome en la excelente respuesta de @kemsky, he implementado una variante de Pipe que corrige un par de problemas de implementación:

  • Funcionará correctamente con angular 2 final y en adelante.
  • deja de votar cuando se destruye
  • utiliza un retroceso simplista para disminuir el intervalo de sondeo consistente con la salida

Puede encontrar el código de especificación de la tubería completa en esta lista: https://gist.github.com/JohannesRudolph/8e6de056d9e33353f940d9da9e6ffd82


Creo que no está relacionado con su tubería sino con la forma en que Angular2 detecta los cambios. Detecta cambios basados ​​en referencias, es decir, si las referencias enlazadas cambian y no si los elementos en ellas se actualizan.

Vea la siguiente muestra:

@Component({ selector: ''my-app'', template: ` <div>{{val | pdate}}</div> `, pipes: [ DatePipe ] }) export class AppComponent { constructor() { this.val = new Date(); setTimeout(() => { this.val = new Date(); // Updates view }, 1000); setTimeout(() => { this.val.setTime((new Date().getTime()); // Doesn''t update view }, 2000); } }

Consulte thisx plunkr: https://plnkr.co/edit/kJdi1wx0iu9tDx8yTmRx?p=preview .


Debe actualizar la referencia de ''fecha'' para activar la detección de cambios de Angular2, con un setTimeout(()=>this.date=new Date(), period) por ejemplo, como lo señaló Thierry.

¿Realmente necesitas una actualización cada segundo? La actualización cada 60 segundos puede ser lo suficientemente buena en función de su caso de uso y puede mostrar "justo ahora" o "hace menos de un minuto" durante los primeros 60 segundos.

Pero si realmente quieres los segundos, solo necesitas actualizarlos cada segundo durante los primeros 60 segundos. El setTimeout(1000) puede convertirse en setTimeout(60000) , para minimizar la sobrecarga.


Finalmente lo puse en funcionamiento, bastante desafiante y requiere ajustes de intervalo :)

import {Pipe, ChangeDetectorRef} from ''angular2/core''; import {Observable} from ''rxjs/Observable''; import {AsyncPipe} from ''angular2/common''; @Pipe({ name: ''messageTime'', pure: false }) export class MessageTimePipe extends AsyncPipe { value:Date; timer:Observable<string>; constructor(ref:ChangeDetectorRef) { super(ref); } transform(obj:any, args?:any[]):any { if (obj instanceof Date) { this.value = obj; if(!this.timer) { this.timer = this.getObservable(); } return super.transform(this.timer, args); } return super.transform(obj, args); } private getObservable() { return Observable.interval(1000).startWith(0).map(()=> { var result:string; // current time let now = new Date().getTime(); // time since message was sent in seconds let delta = (now - this.value.getTime()) / 1000; // format string if (delta < 10) { result = ''jetzt''; } else if (delta < 60) { // sent in last minute result = ''vor '' + Math.floor(delta) + '' Sekunden''; } else if (delta < 3600) { // sent in last hour result = ''vor '' + Math.floor(delta / 60) + '' Minuten''; } else if (delta < 86400) { // sent on last day result = ''vor '' + Math.floor(delta / 3600) + '' Stunden''; } else { // sent more than one day ago result = ''vor '' + Math.floor(delta / 86400) + '' Tagen''; } return result; }); }; }


Una solución de moment.js . Trabajando / probado en Angular 6:

import { ChangeDetectorRef, NgZone, Pipe, PipeTransform } from ''@angular/core''; import * as moment from ''moment''; moment.locale("de"); // set your language @Pipe({ name:''timeago'', pure:false }) export class TimeagoPipe implements PipeTransform { private timer: number; constructor(private changeDetectorRef: ChangeDetectorRef, private ngZone: NgZone) {} transform(value:string) { this.removeTimer(); let d = new Date(value); let now = new Date(); let seconds = Math.round(Math.abs((now.getTime() - d.getTime())/1000)); let timeToUpdate = (Number.isNaN(seconds)) ? 1000 : this.getSecondsUntilUpdate(seconds) *1000; this.timer = this.ngZone.runOutsideAngular(() => { if (typeof window !== ''undefined'') { return window.setTimeout(() => { this.ngZone.run(() => this.changeDetectorRef.markForCheck()); }, timeToUpdate); } return null; }); return moment(d).fromNow(); } ngOnDestroy(): void { this.removeTimer(); } private removeTimer() { if (this.timer) { window.clearTimeout(this.timer); this.timer = null; } } private getSecondsUntilUpdate(seconds:number) { let min = 60; let hr = min * 60; let day = hr * 24; if (seconds < min) { // less than 1 min, update every 2 secs return 2; } else if (seconds < hr) { // less than an hour, update every 30 secs return 30; } else if (seconds < day) { // less then a day, update every 5 mins return 300; } else { // update every hour return 3600; } } }