Основываясь на вашем коде map(i => this.time - i)
, я считаю, что вам нужен не таймер, а обратный отсчет. Итак, я пойду на демонстрацию с обратным отсчетом, но если вам действительно нужен таймер, вы должны иметь возможность работать с кодом обратного отсчета, как очень похожим.
При работе с наблюдаемым старайтесь не:
- переназначить наблюдаемую стоимость
- использовать
subscribe
Вот мое предложение для обратного отсчета:
Сторона TS:
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
public countdownControl: FormControl = new FormControl(5);
public startCountdown$$: Subject<void> = new Subject();
public countdown$: Observable<number> = this.startCountdown$$.pipe(
withLatestFrom(this.countdownControl.valueChanges.pipe(startWith(this.countdownControl.value))),
switchMap(([_, countdownStartValueSeconds]) =>
timer(0, 1000).pipe(
map((_, index) => countdownStartValueSeconds - index),
takeWhile(v => v >= 0)
)
)
);
}
Сторона HTML:
<h1>{{ countdown$ | async }}</h1>
Number of seconds for the countdown:
<input type="number" step="1" [formControl]="countdownControl">
<button (click)="startCountdown$$.next()">Start again</button>
Обратите внимание, что я присваиваю наблюдаемое значение только один раз, никогда после, и что подписки нет вообще.
Если время начала статическое, вы можете немного упростить этот код, удалив withLatestFrom
, но я подумал, что это будет хороший пример, чтобы показать, как иметь переменную, которую мы можем обновить для времени начала.
Примечание: Конечно (и благодаря switchMap
здесь), если таймер запущен, и вы хотите его перезапустить, просто нажмите кнопку запуска еще раз.
Вот рабочая демонстрация: https://stackblitz.com/edit/angular-ivy-gvsn66?embed=1&file=src/app/app.component.ts
person
maxime1992
schedule
24.11.2020
timer
, у вас будет надежный способ сбросить обратный отсчет. stackoverflow.com/questions/64676617/pause-an- interval-rxjs / - person Mrk Sef   schedule 24.11.2020