Je veux un compte à rebours comme celui-ci:
http://codepen.io/garethdweaver/pen/eNpWBb
mais dans angular 2, j'ai trouvé ce plunkr qui ajoute 1 à un nombre tous les 500 millisecondes:
https://plnkr.co/edit/pVMEbbGSzMwSBS4XEXJI?p=preview
c'est le code:
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;
}):
}
}
Mais je veux avoir une date prenant une seconde jusqu'à atteindre 0.
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();
}
}
HTML:
<my-app inputDate="January 1, 2018 12:00:00">Loading...</my-app>
Quelques modifications apportées à la réponse de 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 );
}
}
Ceci est une version un peu simplifiée avec une date codée en dur et renvoyant quatre sorties différentes (jours - heures - minutes - secondes) que vous pouvez mettre bien dans quatre cases:
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;
}
}
Je pensais qu'il était plus logique de créer le minuteur en tant que service afin d'avoir plus de flexibilité lors de la création de mes vues (utilisez le modèle Time renvoyé comme vous le souhaitez dans vos composants). Il crée un nouvel observable lors de la souscription afin que chaque abonné obtienne son propre observable. En bref, vous pouvez créer autant de minuteries en même temps que vous le souhaitez avec ce service. Veillez à inclure ce service dans le groupe de votre fournisseur AppModule afin de pouvoir l'utiliser dans votre application.
Un service:
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))
}
}
Maintenant, utilisez-le dans un composant:
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'))
}
MISE À JOUR POUR RXJS 5.5 +
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 );
}
}
Voici une solution que j'ai récemment proposée pour mon projet. Il vérifie entre une heure d'ouverture de la porte d'un événement et l'heure de l'événement principal du même événement. Ceci utilise Momentjs.
J'ai du code dans la fonction onChanges au cas où une heure d'événement change dans ma base de feu, ce qui est très improbable, mais j'aime bien le fait qu'il puisse le détecter et le mettre à jour à la volée.
Composant:
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>
Produit: '2 jours 6 heures 59 minutes 42' etc