代码之家  ›  专栏  ›  技术社区  ›  tilo

用moment.js自动更新相对时间显示

  •  1
  • tilo  · 技术社区  · 7 年前

    给定一个项目列表(可以将其视为与多条消息的聊天),我想使用 显示每个项目的相对时间(例如自创建以来)。

    每个项目都有自己的组件,使用以下代码显示相对时间:

    get timeFromNow(): string {
      return moment(this.pageLoaded).fromNow(); // pageLoaded is a JS Date
    }
    

    问题是组件不会更新相对时间的显示,因为原始输入( pageLoaded 在上面的例子中)不会改变。

    我的问题是:有没有处理这种情况的最佳做法?目前,我正在使用 markForCheck 属于 ChangeDetectorRef 触发重新渲染。但是,我不确定这是否是一个好的方法性能方面。

    我创造了一个简单的 demo on Stackblitz 是的。在演示中,我使用前面提到的 标记检查 触发更新。

    2 回复  |  直到 7 年前
        1
  •  4
  •   a better oliver    7 年前

    从技术角度来看,你有一个很好的解决方案。如果你想要一个更好的设计,那么进入反应式编程的世界。

    不用手动开始检查,您可以使用流并让Angular完成以下工作:

    export class MomentComponent implements OnInit  {
      pageLoaded: Moment;
      timeFromNow: Observable<string>;
    
      ngOnInit() {
        this.pageLoaded = moment(new Date());
    
        this.timeFromNow = interval(1000).pipe(
                             map(() => this.pageLoaded.fromNow()),
                             distinctUntilChanged()
                           );
      }
    }
    

    interval 工作方式如下 setInterval 在你的例子中:它每1000毫秒发出一个值,然后我们用一个时间字符串替换这个值。就这样。每秒都会发出一个新的时间字符串。我补充说 distinctUntilChanged() 因此,新值只有在与旧值不同时才会发出。

    在模板中,可以使用 async 管道:

    template: `Page loaded: <span class="relativeTime">{{ timeFromNow | async}}</span>`
    

    当发出新的时间字符串时,html将被更新。没有不必要的检查和计算。作为奖励使用 异步 管道当组件被破坏而您没有创建内存泄漏时,计时器将自动取消。

    你可以检查 forked demo 是的。

        2
  •  2
  •   Eric Aya    6 年前

    更好的解决方案是 timer(0, 1000) 而不是 interval(1000) .这将立即开火,然后每秒钟。

    http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-timer

    推荐文章