Автоматически обновлять отображение относительного времени с Moment.js - PullRequest
0 голосов
/ 01 июля 2018

Учитывая список элементов (представьте, что это чат с несколькими сообщениями), я хотел бы использовать для отображения относительного времени (например, с момента создания) для каждого элемента.

Каждый элемент имеет свой компонент, и относительное время отображается с помощью следующего кода:

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

Проблема в том, что компонент не будет обновлять отображение относительного времени, поскольку исходный ввод (pageLoaded в приведенном выше примере) не изменится.

Мой вопрос: есть ли лучшая практика для работы с таким сценарием? В настоящее время я использую markForCheck из ChangeDetectorRef для запуска повторного рендеринга. Однако я не уверен, что это хороший метод с точки зрения производительности.

Я создал простую демонстрацию по Stackblitz . В демоверсии я использую вышеупомянутый markForCheck для запуска обновления.

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Еще лучшее решение - использовать timer(0, 1000) вместо interval(1000). Это будет немедленно срабатывать, а затем каждую секунду.

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

0 голосов
/ 01 июля 2018

С технической точки зрения у вас есть хорошее решение. Если вы хотите лучшего дизайна, то войдите в мир реактивного программирования.

Вместо ручного запуска проверки вы можете использовать поток и позволить 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 pipe:

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

HTML будет обновляться при появлении новой строки времени. Нет ненужных проверок и расчетов. В качестве бонуса при использовании канала async таймер автоматически отменяется, когда компонент уничтожается, и вы не создаете утечку памяти.

Вы можете проверить демо-версию .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...