Je suis prêt à faire un compte à rebours dans Angular 2 qui commence à 60 (c'est-à-dire 59, 58,57, etc.).
Pour cela j'ai le suivant:
constructor(){
Observable.timer(0,1000).subscribe(timer=>{
this.counter = timer;
});
}
Ce qui précède coche chaque seconde, ce qui va bien; cependant, il passe dans un ordre croissant à un nombre illimité. Je ne suis pas sûr s'il y a un moyen de le modifier afin que je puisse avoir un compte à rebours.
Il y a plusieurs façons d'y parvenir, un exemple de base consiste à utiliser l'opérateur take
import { Observable, timer } from 'rxjs';
import { take, map } from 'rxjs/operators';
@Component({
selector: 'my-app',
template: `<h2>{{countDown | async}}</h2>`
})
export class App {
counter$: Observable<number>;
count = 60;
constructor() {
this.counter$ = timer(0,1000).pipe(
take(this.count),
map(() => --this.count)
);
}
}
Voici un live plnkr
Une meilleure façon! créer une contre-directive
import { Directive, Input, Output, EventEmitter, OnChanges, OnDestroy } from '@angular/core';
import { Subject, Observable, SubscriptionLike, timer } from 'rxjs';
import { switchMap, take, tap } from 'rxjs/operators';
@Directive({
selector: '[counter]'
})
export class CounterDirective implements OnChanges, OnDestroy {
private counter$ = new Subject<any>();
private countSub$: SubscriptionLike;
@Input() counter: number;
@Input() interval: number;
@Output() value = new EventEmitter<number>();
constructor() {
this.countSub$ = this.counter$.pipe(
switchMap((options: any) =>
timer(0, options.interval).pipe(
take(options.count),
tap(() => this.value.emit(--options.count))
)
)
).subscribe();
}
ngOnChanges() {
this.counter$.next({ count: this.counter, interval: this.interval });
}
ngOnDestroy() {
this.countSub$.unsubscribe();
}
}
Utilisation:
<ng-container [counter]="60" [interval]="1000" (value)="count = $event">
<span> {{ count }} </span>
</ng-container>
Voici un live stackblitz
Importer dans le composant:
import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/timer";
import "rxjs/add/operator/finally";
import "rxjs/add/operator/takeUntil";
import "rxjs/add/operator/map";
Compte à rebours:
countdown: number;
startCountdownTimer() {
const interval = 1000;
const duration = 10 * 1000;
const stream$ = Observable.timer(0, interval)
.finally(() => console.log("All done!"))
.takeUntil(Observable.timer(duration + interval))
.map(value => duration - value * interval);
stream$.subscribe(value => this.countdown = value);
}
Html:
<div class="panel panel-default">
<div class="panel-heading">
<h2 class="panel-title">Countdown timer</h2>
</div>
<div class="panel-body">
<div>
<label>value: </label> {{countdown}}
</div>
<div>
<button (click)="startCountdownTimer()" class="btn btn-success">Start</button>
</div>
</div>
</div>