我正在尝试创造一个'之前的'我的Angular 2应用程序的管道。
它应该将日期转换为字符串,例如“5分钟前”'或者' 60秒前'。它到目前为止工作得很好,但在第一次计算后它没有更新。如果给定日期是例如5秒前,则显示“5秒前”'但在此之后永远不会改变。
我已经尝试过设置管道' pure'价值为假,但没有帮助。
这是我的代码:
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;
}
}
我正在使用这样的过滤器:
打字稿:
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>
答案 0 :(得分:24)
我刚用过这个:
https://www.npmjs.com/package/time-ago-pipe
function sheetname() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getActiveRange().getSheet();
SpreadsheetApp.flush();
return s.getName();
}
然后在@NgModule中使用它:
npm install time-ago-pipe --save
在模板中:
import {TimeAgoPipe} from 'time-ago-pipe
@NgModule({
imports: [... etc ...],
declarations: [AppComponent, ...etc..., TimeAgoPipe],
bootstrap: [AppComponent]
})
不要重新发明轮子,除非你打算详细了解轮子。
答案 1 :(得分:18)
最后让它发挥作用,非常具有挑战性,需要间隔调整:)
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;
});
};
}
答案 2 :(得分:4)
基于@kemsky的优秀答案,我实现了Pipe的一个变种,修复了一些实现问题:
您可以在此要点中找到完整的管道+规格代码: https://gist.github.com/JohannesRudolph/8e6de056d9e33353f940d9da9e6ffd82
答案 3 :(得分:1)
使用此https://www.npmjs.com/package/time-ago-pipe
一个非常简单,轻巧的Angular管道,用于将日期字符串转换为以前的时间
用法:
npm install time-ago-pipe --save
import {TimeAgoPipe} from 'time-ago-pipe';
@NgModule({
imports: [... etc ...],
declarations: [..., TimeAgoPipe, ... ]
})
<span>{{your_date | timeAgo}}</span>
答案 4 :(得分:1)
可接受的答案不适用于角度为7+的情况。
我遵循了这个答案,并为越南语定制。
https://stackoverflow.com/a/61341940/4964569
我分享关注的人。
#!/usr/bin/env python3
name = 'john smith'
age = 25
location = 'chicago'
print ('My name is %s, and I live in %s. I am %s years old.' % (name, location, str(age)))
答案 5 :(得分:0)
我认为它与您的管道无关,而是与Angular2检测到更改的方式有关。它根据引用检测更改,即绑定引用是否更改,而不是更新它们中的元素。
请参阅以下示例:
@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);
}
}
参见thisx plunkr:https://plnkr.co/edit/kJdi1wx0iu9tDx8yTmRx?p=preview。
答案 6 :(得分:0)
你需要更新'date'引用以触发Angular2的变化检测,例如,setTimeout(()=>this.date=new Date(), period)
,正如Thierry指出的那样。
你真的需要每秒更新一次吗? 根据您的使用情况,每60秒更新一次可能就足够了,并且可以在前60秒内显示“刚刚”或“不到一分钟”。
但如果你真的想要秒,你只需要在前60秒内每秒更新一次。然后,setTimeout(1000)
可以变为setTimeout(60000)
,以最大限度地减少开销。
答案 7 :(得分:0)
您需要运行以下命令 npm install time-ago-pipe --save 才能将time-ago npm软件包安装在角度应用程序中 例如:PS D:\ D \ TimeAgo> npm install time-ago-pipe --save。运行此命令后,将添加软件包。 Image shows how to add import {TimeAgoPipe} from 'time-ago-pipe'; in app.module and put TimeAgoPipe in Declarations [传递来自组件的输入o/p
答案 8 :(得分:0)
一个 moment.js 解决方案。在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;
}
}
}
答案 9 :(得分:0)
使用ngx-moment https://github.com/urish/ngx-moment(与Momentjs进行管道集成,并提供i18n支持)