Javascript 角度2的时间倒计时

Javascript 角度2的时间倒计时,javascript,angular,Javascript,Angular,我想要一个这样的日期倒计时: 但在angular 2中,我发现了这个plunkr,它每500毫秒给一个数字加1: 代码如下: import {Component,Input} from 'angular2/core'; import {Observable} from 'rxjs/Rx'; @Component({ selector: 'my-app', template: ` <div> {{message}} <

我想要一个这样的日期倒计时:

但在angular 2中,我发现了这个plunkr,它每500毫秒给一个数字加1:

代码如下:

import {Component,Input} from 'angular2/core';
import {Observable} from 'rxjs/Rx';

@Component({
    selector: 'my-app',
    template: `
      <div>
        {{message}}
      </div>
    `
})
export class AppComponent {   

  constructor() {
    Observable.interval(1000)
              .map((x) => x+1)
              .subscribe((x) => {
                this.message = x;
              }):
  }
}
从'angular2/core'导入{组件,输入};
从'rxjs/Rx'导入{Observable};
@组成部分({
选择器:“我的应用程序”,
模板:`
{{message}}
`
})
导出类AppComponent{
构造函数(){
可观测间隔(1000)
.map((x)=>x+1)
.订阅((x)=>{
这个消息=x;
}):
}
}
但我希望在到达0之前有一秒钟的时间。

从'angular2/core'导入{Component,NgOnInit,ElementRef,OnInit,OnDestroy};
import { Component, NgOnInit, ElementRef, OnInit, OnDestroy } from 'angular2/core';
import { Observable, Subscription } from 'rxjs/Rx';

@Component({
    selector: 'my-app',
    template: `
  <div>
    {{message}}
  </div>
`
})
export class AppComponent implements OnInit, OnDestroy {

    private future: Date;
    private futureString: string;
    private counter$: Observable<number>;
    private subscription: Subscription;
    private message: string;

    constructor(elm: ElementRef) {
        this.futureString = elm.nativeElement.getAttribute('inputDate');
    }

    dhms(t) {
        var days, hours, minutes, seconds;
        days = Math.floor(t / 86400);
        t -= days * 86400;
        hours = Math.floor(t / 3600) % 24;
        t -= hours * 3600;
        minutes = Math.floor(t / 60) % 60;
        t -= minutes * 60;
        seconds = t % 60;

        return [
            days + 'd',
            hours + 'h',
            minutes + 'm',
            seconds + 's'
        ].join(' ');
    }


    ngOnInit() {
        this.future = new Date(this.futureString);
        this.counter$ = Observable.interval(1000).map((x) => {
           return Math.floor((this.future.getTime() - new Date().getTime()) / 1000);
        });

        this.subscription = this.counter$.subscribe((x) => this.message = this.dhms(x));
    }

    ngOnDestroy(): void {
        this.subscription.unsubscribe();
    }
}
从“rxjs/Rx”导入{可观察,订阅}; @组成部分({ 选择器:“我的应用程序”, 模板:` {{message}} ` }) 导出类AppComponent实现OnInit、OnDestroy{ 私人未来:日期; 私人未来字符串:字符串; 专用计数器$:可观察; 私人认购:认购; 私有消息:字符串; 构造函数(elm:ElementRef){ this.futureString=elm.nativeElement.getAttribute('inputDate'); } dhms(t){ var天、小时、分钟、秒; 天数=数学下限(t/86400); t-=天数*86400; 小时=数学楼层(t/3600)%24; t-=小时*3600; 分钟=数学地板(t/60)%60; t-=分钟*60; 秒=t%60; 返回[ 天数+d, 小时数+小时数, 分钟数+m, 秒+秒 ].加入(“”); } 恩戈尼尼特(){ this.future=新日期(this.futureString); 此.counter$=可观察的.interval(1000).map((x)=>{ 返回Math.floor((this.future.getTime()-new Date().getTime())/1000); }); this.subscription=this.counter$.subscripte((x)=>this.message=this.dhms(x)); } ngOnDestroy():void{ this.subscription.unsubscripte(); } }
HTML:

正在加载。。。

这是一个稍微简化的版本,带有硬编码日期并返回四种不同的输出(天-小时-分钟-秒),您可以很好地将它们放在四个框中:

export class HomePage {

    // Hardcoded date
    private eventDate: Date = new Date(2018, 9, 22);

    private diff: number;
    private countDownResult: number;
    private days: number;
    private hours: number;
    private minutes: number;
    private seconds: number;

    constructor(public navCtrl: NavController ) {

        Observable.interval(1000).map((x) => {
                this.diff = Math.floor((this.eventDate.getTime() - new Date().getTime()) / 1000);
            }).subscribe((x) => {           
                this.days = this.getDays(this.diff);
                this.hours = this.getHours(this.diff);
                this.minutes = this.getMinutes(this.diff);
                this.seconds = this.getSeconds(this.diff);
            });
    }

    getDays(t){
        return Math.floor(t / 86400);
    }

    getHours(t){
        const days = Math.floor(t / 86400);
        t -= days * 86400;
        const hours = Math.floor(t / 3600) % 24;
        return hours;
    }

    getMinutes(t){
        const days = Math.floor(t / 86400);
        t -= days * 86400;
        const hours = Math.floor(t / 3600) % 24;
        t -= hours * 3600;
        const minutes = Math.floor(t / 60) % 60;
        return minutes;
    }

    getSeconds(t){
        const days = Math.floor(t / 86400);
        t -= days * 86400;
        const hours = Math.floor(t / 3600) % 24;
        t -= hours * 3600;
        const minutes = Math.floor(t / 60) % 60;
        t -= minutes * 60;
        const seconds = t % 60;
        return seconds;
    }

}

这是我最近在项目中提出的一个解决方案。它检查事件的闸门打开时间和同一事件的主事件时间。这使用Momentjs

我在onChanges函数中有代码,以防firebase中的事件时间发生变化,这是不太可能的,但我喜欢它可以随时进行更新

组成部分:

import { Component, OnInit, Input, OnChanges } from '@angular/core';
import { Observable } from "rxjs/Rx"
import { RoundService } from '../../round.service'
import * as moment from 'moment-timezone';

@Component({
  selector: 'race-countdown',
  templateUrl: './race-countdown.component.html',
  styleUrls: ['./race-countdown.component.scss']
})
export class RaceCountdownComponent implements OnChanges,OnInit{

    @Input() activeRound;

    public time:number;
    public timeToGates:number;
    public timeToMains:number;  
    public countDown:Observable<any>;
    public currentUnix = moment().unix();

    constructor(private rs:RoundService) { }

    ngOnChanges() {

    this.timeToGates = this.activeRound.gateOpenUnix - this.currentUnix;
    this.timeToMains = this.activeRound.mainEventUnix - this.currentUnix;

    if(this.timeToGates < 0)
        this.time = this.timeToMains
    else 
        this.time = this.timeToGates

  }

  ngOnInit() {

    this.countDown = Observable.interval(1000)
                                          .map(res=>{ return this.time = this.time-1 })
                                          .map(res=> {

                                            let timeLeft = moment.duration(res, 'seconds');
                                            let string:string = '';

                                            // Days.
                                            if(timeLeft.days() > 0) 
                                                string += timeLeft.days() + ' Days'

                                            // Hours.
                                            if(timeLeft.hours() > 0) 
                                                string += ' ' + timeLeft.hours() + ' Hours'

                                            // Minutes.
                                            if(timeLeft.minutes() > 0)
                                                string += ' ' + timeLeft.minutes() + ' Mins'

                                            // Seconds.
                                            string += ' ' + timeLeft.seconds(); 

                                            return string;

                                          })

  }

}
import {Component, OnInit} from '@angular/core';
import {Time, TimerService} from '../timer.service';

@Component({
  selector: 'app-timer',
  template: `
   <ng-container *ngIf="time1$ | async as time1"
     <pre>{{time1.days}}days {{time1.hours}}hours {{time1.minutes}} minutes {{time1.seconds}}seconds<pre>
     <br>
   <ng-container>

   <ng-container *ngIf="time2$ | async as time2"
     <pre>{{time2.days}}days {{time2.hours}}hours {{time2.minutes}} minutes {{time2.seconds}}seconds<pre>
     <br>
   <ng-container>
`
})
export class TimerComponent implements OnInit {

  time1$: Observable<Time>;
  time2$: Observable<Time>;

  constructor(private timerService: TimerService) {}

  ngOnInit() {

    this.time1$ = this.timerService.timer(new Date('June 4, 2020 15:37:25'))

    this.time2$ = this.timerService.timer(new Date('August 9, 2041 15:37:25'))

  }
从'@angular/core'导入{Component,OnInit,Input,OnChanges};
从“rxjs/Rx”导入{Observable}
从“../../round.service”导入{RoundService}
从“时刻时区”导入*作为时刻;
@组成部分({
选择器:“比赛倒计时”,
templateUrl:'./race countdown.component.html',
样式URL:['./比赛倒计时.component.scss']
})
导出类RaceCountdownComponent实现OnChanges、OnInit{
@输入()活动轮;
公众时间:数字;
公共时间:数字;
公共计时器:数字;
公众倒数:可见;
public currentUnix=moment().unix();
构造函数(专用rs:RoundService){}
ngOnChanges(){
this.timeToGates=this.activeRound.gateOpenUnix-this.currentUnix;
this.timeToMains=this.activeRound.mainEventUnix-this.currentUnix;
如果(this.timeToGates<0)
this.time=this.timeToMains
其他的
this.time=this.timeToGates
}
恩戈尼尼特(){
this.countDown=可观察的间隔(1000)
.map(res=>{返回this.time=this.time-1})
.map(res=>{
让timeLeft=时刻持续时间(res,'秒');
让string:string='';
//天。
如果(timeLeft.days()>0)
字符串+=timeLeft.days()+“days”
//时间。
如果(timeLeft.hours()>0)
字符串+=''+timeLeft.hours()+'hours'
//分钟。
如果(timeLeft.minutes()>0)
字符串+=''+timeLeft.minutes()+'Mins'
//秒。
字符串+=''+timeLeft.seconds();
返回字符串;
})
}
}
HTML:

{{倒计时|异步}
产生:
“2天6小时59分钟42”等对约翰尼菲蒂齐奥的答案做了一些修改


我认为将计时器创建为服务更有意义,这样在创建视图时就可以有更多的灵活性(在组件中使用返回的时间模型)。它在订阅时创建一个新的可观察对象,以便每个订户都获得自己的可观察对象。简而言之,您可以使用此服务同时创建任意数量的计时器。请确保将此服务包括在AppModule提供程序的阵列中,以便您可以在整个应用程序中使用它

服务:

import { Injectable } from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/defer';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/map';

export interface Time {
  days: number;
  hours: number;
  minutes: number;
  seconds: number;
}

@Injectable()
export class TimerService {

  constructor() { }

  private createTimeObject(date: Date): Time {

    const now = new Date().getTime();
    const distance = date.getTime() - now;

    let time: Time = {days: 0, hours: 0, minutes: 0, seconds: 0};
    time.days = Math.floor(distance / (1000 * 60 * 60 * 24));
    time.hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    time.minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    time.seconds = Math.floor((distance % (1000 * 60)) / 1000);
    return time;
  }

  timer(date: Date): Observable<Time> {
      return Observable.interval(1000)
        .map(() => this.createTimeObject(date))
  }
}
从'@angular/core'导入{Injectable};
从“rxjs/Observable”导入{Observable};
导入“rxjs/add/observable/defer”;
导入“rxjs/add/observable/interval”;
导入'rxjs/add/operator/map';
导出接口时间{
天数:个数;
小时数:个;
分钟:数字;
秒:数字;
}
@可注射()
导出类TimerService{
构造函数(){}
私有createTimeObject(日期:日期):时间{
const now=new Date().getTime();
const distance=date.getTime()-现在;
让
import {Observable} from 'rxjs/Rx';
import {Component, OnInit} from '@angular/core';

export class TimerComponent implements OnInit {

    private _trialEndsAt;
    private _diff: number;
    private _days: number;
    private _hours: number;
    private _minutes: number;
    private _seconds: number;

    constructor() {}

    ngOnInit() {  
        this._trialEndsAt = "2017-02-28";
        Observable.interval(1000).map((x) => {
            this._diff = Date.parse(this._trialEndsAt) - Date.parse(new Date().toString());
        }).subscribe((x) => {           
            this._days = this.getDays(this._diff);
            this._hours = this.getHours(this._diff);
            this._minutes = this.getMinutes(this._diff);
            this._seconds = this.getSeconds(this._diff);
        });
    }

    getDays(t){
        return Math.floor( t/(1000*60*60*24) );
    }

    getHours(t){
        return Math.floor( (t/(1000*60*60)) % 24 );
    }

    getMinutes(t){
        return Math.floor( (t/1000/60) % 60 );
    }

    getSeconds(t){
        return Math.floor( (t/1000) % 60 );
    }

}
import { Injectable } from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/defer';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/map';

export interface Time {
  days: number;
  hours: number;
  minutes: number;
  seconds: number;
}

@Injectable()
export class TimerService {

  constructor() { }

  private createTimeObject(date: Date): Time {

    const now = new Date().getTime();
    const distance = date.getTime() - now;

    let time: Time = {days: 0, hours: 0, minutes: 0, seconds: 0};
    time.days = Math.floor(distance / (1000 * 60 * 60 * 24));
    time.hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    time.minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
    time.seconds = Math.floor((distance % (1000 * 60)) / 1000);
    return time;
  }

  timer(date: Date): Observable<Time> {
      return Observable.interval(1000)
        .map(() => this.createTimeObject(date))
  }
}
import {Component, OnInit} from '@angular/core';
import {Time, TimerService} from '../timer.service';

@Component({
  selector: 'app-timer',
  template: `
   <ng-container *ngIf="time1$ | async as time1"
     <pre>{{time1.days}}days {{time1.hours}}hours {{time1.minutes}} minutes {{time1.seconds}}seconds<pre>
     <br>
   <ng-container>

   <ng-container *ngIf="time2$ | async as time2"
     <pre>{{time2.days}}days {{time2.hours}}hours {{time2.minutes}} minutes {{time2.seconds}}seconds<pre>
     <br>
   <ng-container>
`
})
export class TimerComponent implements OnInit {

  time1$: Observable<Time>;
  time2$: Observable<Time>;

  constructor(private timerService: TimerService) {}

  ngOnInit() {

    this.time1$ = this.timerService.timer(new Date('June 4, 2020 15:37:25'))

    this.time2$ = this.timerService.timer(new Date('August 9, 2041 15:37:25'))

  }
import {map} from 'rxjs/internal/operators';
import { Component, OnInit } from '@angular/core';
import {interval, Observable} from 'rxjs';

@Component({
  selector: 'app-countdown',
  templateUrl: './countdown.component.html',
  styleUrls: ['./countdown.component.css']
})
export class CountdownComponent implements OnInit {

  private _trialEndsAt;

  private _diff: number;
  private _days: number;
  private _hours: number;

  private _minutes: number;

  private _seconds: number;

  constructor() {}

  ngOnInit() {

      this._trialEndsAt = "2017-02-28";

      interval(3000).pipe(
        map((x) => {this._diff = Date.parse(this._trialEndsAt) - Date.parse(new Date().toString());
          })).subscribe((x) => {
              this._days = this.getDays(this._diff);
              this._hours = this.getHours(this._diff);
              this._minutes = this.getMinutes(this._diff);
              this._seconds = this.getSeconds(this._diff);
          });
  }

  getDays(t) {
      return Math.floor( t / (1000 * 60 * 60 * 24) );
  }

  getHours(t) {
      return Math.floor( (t / (1000 * 60 * 60)) % 24 );
  }

  getMinutes(t) {
      return Math.floor( (t / 1000 / 60) % 60 );
  }

  getSeconds(t) {
      return Math.floor( (t / 1000) % 60 );
  }

}