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>
Obtener tiempo en AngularJs2
Debe ejecutar este comando npm install time-ago-pipe --save para instalar el paquete del paquete npm de time now ago en su aplicación angular ej: PS D: / D / TimeAgo> npm install time-ago-pipe --save. Después de ejecutar este comando se agregará el paquete. La imagen muestra cómo agregar importación {TimeAgoPipe} desde ''time-ago-pipe''; en app.module y ponga TimeAgoPipe en Declaraciones [Pase la entrada del componente o/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;
}
}
}