Angular 2多重倒计时管道

8

我希望能够创建一个Angular 2/4倒计时管道。

当然,我可以创建单独的倒计时,但如何创建多个倒计时呢?

我想要以下输入:

<span [time]="unix timestamp here">Countdown will count here</span>

例如:

<span [time]="1500503492">Countdown will count here</span>
<span [time]="15005034392">Countdown will count here</span>
<span [time]="1500503492">Countdown will count here</span>

我该如何实现无论有多少个,都可以使所有内容正常工作?
到目前为止,我尝试的只是像以下这样的单一倒计时:
time = 30;
setInterval(() => {
  this.currentTime = new Date().getTime();
  if (this.time > 0) {
    this.time = this.time - 1;
  }
}, 1000);

{{ time}}
1个回答

11

我认为你正在寻找一个组件(Component),而不是管道(Pipe)或指令(Directive)。

这个组件应该可以满足你的需求:

import { Component, Input, ChangeDetectionStrategy, ChangeDetectorRef, OnDestroy } from '@angular/core';

@Component({
  selector: 'ngx-countdown',
  template: '{{ displayTime }}',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CountdownComponent implements OnDestroy {
  private _time: number;
  private _timing: number = 1000;
  private _interval;

  @Input()
  public set time(value: string | number) {
    this._time = parseInt(value as string, 10);
    this._startTimer();
  }

  @Input()
  public set timing(value: string | number) {
    this._timing = parseInt(value as string, 10);
    this._startTimer();
  }

  @Input()
  public format: string = '{dd} days {hh} hours {mm} minutes {ss} seconds';

  public get delta() {
    let date = new Date();
    return Math.max(0, Math.floor((this._time - date.getTime()) / 1000));
  }

  public get displayTime() {
    let days, hours, minutes, seconds, delta = this.delta, time = this.format;

    days = Math.floor(delta / 86400);
    delta -= days * 86400;
    hours = Math.floor(delta  / 3600) % 24;
    delta -= hours * 3600;
    minutes = Math.floor(delta  / 60) % 60;
    delta -= minutes * 60;
    seconds = delta % 60;

    time = time.replace('{dd}', days);
    time = time.replace('{hh}', hours);
    time = time.replace('{mm}', minutes);
    time = time.replace('{ss}', seconds);

    return time;
  }

  constructor(private _changeDetector: ChangeDetectorRef) { }

  ngOnDestroy() {
    this._stopTimer();
  }

  private _startTimer() {
    if(this.delta <= 0) return;
    this._stopTimer();
    this._interval = setInterval(() => {
      this._changeDetector.detectChanges();
      if(this.delta <= 0) {
        this._stopTimer();
      }
    }, this._timing);
  }

  private _stopTimer() {
    clearInterval(this._interval);
    this._interval = undefined;
  }
}

你可以输入想要倒计时的Unix时间戳,并定义倒计时应该显示的格式。
以下是使用上述组件的示例

谢谢!但是我在离开当前视图后遇到了倒计时错误(因为所有订阅的内容都被销毁了)。由于detectChanges,如何销毁所有不存在的倒计时? - maria
更新了代码,并添加了一个ngOnDestroy生命周期钩子,用于在组件销毁时停止计时器。 - cyr_x
太棒了。如果我想在计数器达到某个值时停止它,我该怎么做? - KhoPhi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接