Как остановить интервал / таймер rxjs - PullRequest
0 голосов
/ 16 мая 2019

Я нашел пару примеров, где можно запустить / остановить таймер или интервал rxjs, однако у меня возникают проблемы с остановкой таймера.

Фрагмент HTML ниже:

К вашему сведению: При первом нажатии autoPlay() мой интервал автовоспроизведения сработает. Повторное нажатие отключит автоматическое воспроизведение.

Событие My Angular (click) вызовет autoPlay() просто отлично, а мой this.toggleMe работает как положено (переключает значение между true и false каждую 1 секунду).

<mat-slide-toggle #toggleMe color="primary" [checked]="toggleMe"></mat-slide-toggle>
<div>
  <mat-icon svgIcon="auto-flipper" (click)="autoPlay()"></mat-icon>
</div>

<!-- example of the two panels that are shown/hidden based on slide-toggle above -->
<show-panel-one
  [hidden]="toggleMe.checked"
></show-panel-one>

<show-panel-two
  [hidden]="!toggleMe.checked"
></show-panel-two>

Однако я пытаюсь очистить интервал с помощью Subject; а именно this.stopPlay$.next();. Но это не остановит интервал.

import { Component, ... } from "@angular/core";

@Component({
    selector: "auto-play",
    templateUrl: "./auto-play.component.html",
})

export class MyTestComponent implements OnChanges, OnInit {

autoPlay = false;
stopPlay$: Subject<any> = new Subject();
@ViewChild("examToggle") examToggle: MatSlideToggle;

constructor() {}

autoPlay(): void {
	this.autoPlay = !this.autoPlay;
	if (!this.autoPlay) {
		this.stopPlay$.next();
	}
	const autoPlayInter = interval(1000);
	autoPlayInter.subscribe(() => {
		this.toggleMe.checked = !this.toggleMe.checked;
	});
	autoPlayInter.pipe(
		// map((_) => {}),
		takeUntil(this.stopPlay$),  // Shouldn't the .next() above trigger the timer stop ?
	);        
 }
 
}

Было бы здорово узнать, что я делаю не так.

Некоторые из моих ссылок:

Как остановить таймер rxjs Перезапустить таймер с интервалом rxjs

* ОБНОВЛЕНИЕ - ФИНАЛЬНАЯ ВЕРСИЯ *

autoSwitch(): void {
        this.autoPlay = !this.autoPlay;

        if (this.autoPlay) {
            this.autoPlayInter = timer(0, 2000)
                .pipe(
                    takeUntil(this.stopPlay$),
                    tap((_) => (this.toggleMe.checked = !this.toggleMe.checked)),
                )
                .subscribe();
        } else {

            this.stopPlay$.next(); // this stops the timer
        }
    }

Ответы [ 2 ]

0 голосов
/ 16 мая 2019

в ответ на обновленный код:

должен измениться на что-то вроде следующего:

autoPlay() {
    this.autoPlay = !this.autoPlay;

    if (this.autoPlay) {
        this.autoPlayInter = interval(2000);
        this.autoPlayInter
            .pipe(takeUntil(this.stopPlay$))
            .subscribe(() => {
                this.examToggle.checked = !this.examToggle.checked;
            });
    } else {
        this.stopPlay$.next();
    }
 }
0 голосов
/ 16 мая 2019

Вы должны изменить это:

const autoPlayInter = interval(1000);
autoPlayInter.subscribe(() => (this.toggleMe.checked = !this.toggleMe.checked));
autoPlayInter.pipe(takeUntil(this.stopPlay$));  

к этому:

const autoPlayInter = interval(1000);
autoPlayInter
    .pipe(takeUntil(this.stopPlay$))
    .subscribe(() => (this.toggleMe.checked = !this.toggleMe.checked));

причина: takeUntil влияет на подписчика, а не на источник.

...