2016-04-06 14 views
13

Я хочу иметь дату обратного отсчета, как это:Время CountDown в угловом 2

http://codepen.io/garethdweaver/pen/eNpWBb

но в угловой 2, я нашел эту plunkr, что добавляет 1 к числу каждый 500 миллисекунды:

https://plnkr.co/edit/pVMEbbGSzMwSBS4XEXJI?p=preview

это код:

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; 
       }): 
    } 
} 

Но я хочу, чтобы иметь дату, принимая одну секунду, пока не достигнет 0.

ответ

22
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 diff: number; 
    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) => { 
      this.diff = Math.floor((this.future.getTime() - new Date().getTime())/1000); 
      return x; 
     }); 

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

    ngOnDestroy(): void { 
     this.subscription.unsubscribe(); 
    } 
} 

HTML:

<my-app inputDate="January 1, 2018 12:00:00">Loading...</my-app> 
+0

Да, он работает, как я могу отправить в inputdate переменную из класса, я пытаюсь как это, но я получаю нуль в скрипте.

+0

Вам не нужно attr.Просто использовать [inputDate] должна быть строка, которая анализирует дату. Мой ответ ответил на ваш первоначальный вопрос, пожалуйста, можете ли вы пометить его как правильно? – KnowHoper

+0

@HeySatan Это работает отлично для меня, используя статическую дату, но когда я пытаюсь использовать переменную, я получаю эту ошибку: 'Исправлены ошибки синтаксиса: не могу привязываться к 'inputDate', так как это не известное собственное свойство' , Любая идея, что его вызывает? Использование Angular2 RC.1 – kolli

4

Это немного упрощенная версия с закодированного даты и возвращения четырех различных выходов (дни - часы - минуты - секунды), которые можно легко добавить в четыре окна:

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){ 
     var days; 
     days = Math.floor(t/86400); 

     return days; 
    } 

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

     return hours; 
    } 

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

     return minutes; 
    } 

    getSeconds(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 seconds; 
    } 

} 
+0

Большое спасибо. – Guto

+0

не могли бы вы посмотреть на это: https://stackoverflow.com/questions/44545167/angular2-ionic2-how-to-create-a-countdown-timer-with-hours-mins-secs-and-millis –

0

Вот решение, которое я недавно придумал в своем проекте. Он проверяет время открытия ворот события и время основного события того же события. Это использует 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; 

              }) 

    } 

} 

HTML:

<span>{{countDown | async}}</span> 

Производит: '2 дня 6 часов 59 Мин 42' и т.д.

+1

Как сделать Я вводил время? Получение NaN, когда я запускаю это. –

5

Сделаны некоторые незначительные изменения в ответ Johnnyfittizio в. https://stackoverflow.com/a/40784539/4579897

`

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); 
} 

} `

+0

Работает как очарование! –

1

Я думал, что он сделал больше смысла, чтобы создать таймер как службы, так что я могу иметь больше гибкости при создании своих взглядов (использовать возвращаемый модель времени, однако вы хотите в своих компонентах). Он создает новый наблюдаемый при подписке, поэтому каждый абонент получает свое собственное наблюдение. Короче говоря, вы можете создать столько таймеров одновременно с этой услугой, сколько хотите. Не забудьте включить эту службу в массив поставщика 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)) 
    } 
} 

Теперь использовать его в компоненте:

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')) 

    } 
Смежные вопросы