我非常喜欢angular和ngrx。我正在构建一个与Todoist api集成的番茄钟计时器应用程序。我使用[ngrx / platform示例应用程序作为入门应用程序](https://github.com/ngrx/example-app),它使用带有组件的容器。我最初在纯rxjs中创建了一个计时器,它的功能与它自己应该的一样。我目前正在尝试将计时器集成到我的代码中,该页面来自taskDetail页面,该页面与选定任务页面一起使用。有一个播放/暂停按钮,应该按照它的相应动作进行操作。计时器播放和暂停,但剩余时间未正确显示。我假设因为我没有订阅计时器和/或传递给我应该的方式。这些按钮都调用与输出到selected-task-page.ts相同的功能,它具有pomo-timer-service.ts的提供者
任务detail.ts
timeRemaining: any;
private timerSubscription: Subscription;
constructor(public pomoTimerService: PomoTimerService, private store:
Store<fromTasks.State>) {
this.task$ = store.pipe(select(fromTasks.getSelectedTask));
this.isSelectedTaskInCollection$ = store.pipe(
select(fromTasks.isSelectedTaskInCollection)
);
this.timerSubscription = this.pomoTimerService.getState().subscribe(
timeRemaining => {
this.timeRemaining = timeRemaining;
}
);
}
<button id="resume" name="resumeButton" class="resume-btn"
mat-raised-button color="primary" (click)="resumeCommand($event)"><i class="material-icons">play_arrow</i></button>
<button id="pause" name="pauseButton" class="pause-btn"
mat-raised-button color="primary" (click)="resumeCommand($event)"><i class="material-icons">pause</i></button>
&#13;
以上模板具有输入和输出以下内容:
@Input() timeRemaining: number;
@Input() timerSubscription: Subscription;
@Output() resumeClicked = new EventEmitter();
resumeCommand(action: any) {
this.resumeClicked.emit(action);
}
**在我的selected-task-page.ts模板代码中,我有:
<bc-task-detail
[timeRemaining]="this.pomoTimerService.timeRemaining"
[pomoTitle]="this.pomoTimerService.pomoTitle$"
[pomoCount]="this.pomoTimerService.pomoCount$"
(resumeClicked)="resumeClicked($event)"
(resumeClicked)="resumeClicked($event)">
</bc-task-detail>
&#13;
我有以下内容然后调用该服务。**
(resumeClicked)="resumeClicked($event)"
(resumeClicked)="resumeClicked($event)"
调用:
resumeClicked(event) {
console.log(event);
console.log(event.target);
console.log(event.srcElement);
console.log(event.type);
console.log(event.currentTarget.attributes.name.nodeValue);
console.log(event.currentTarget.attributes.id.nodeValue);
this.pomoTimerService.startTimer(event);
}
在我的pomo-timer.ts中,我有以下
private timerSource = new Subject<any>();
timeRemaining;
timer$ = this.timerSource.asObservable();
setState(state: any) {
this.timerSource.next(state);
}
getState(): Observable<any> {
return this.timerSource.asObservable();
}
然后我在pomo-timer.ts中也有定时器功能:
startTimer(event) {
this.buttonState = event.currentTarget.attributes.name.nodeValue;
this.buttonAction = event.currentTarget.attributes.id.nodeValue;
this.timerToggle = (this.buttonAction === 'resume') ? true : false;
const resumeButton = document.getElementById('resume');
const pauseButton = document.getElementById('pause');
const resetButton = document.getElementById('reset');
const interval$: any = interval(1000).pipe(mapTo(-1));
const pause$ = fromEvent(pauseButton, 'click').pipe(mapTo(false));
const resume$ = fromEvent(resumeButton, 'click').pipe(mapTo(true));
const timer$ = merge(pause$, resume$).pipe(
startWith(interval$),
switchMap(val => (val ? interval$ : empty())),
scan((acc, curr) => (curr ? curr + acc:acc),this.countdownSeconds$),
takeWhile(v => v >= 0),
)
.subscribe(
val => { this.timeRemaining = val; },
() => {
this.resetTimer();
});
}
这个想法是当用户点击播放按钮时,计时器开始倒计时并显示剩余时间,当暂停按钮暂停时。我的一个问题是我应该订阅计时器$还是我应该订阅timerRemaining然后如何订阅它以便它可以进入输入并显示剩余时间,因为它倒计时,最后我甚至需要获取和设置状态的功能?
我感谢任何帮助。先感谢您。
答案 0 :(得分:0)
以下是开始/暂停的方法:
let defaultTime = 2;
let newTime;
let $interval;
const interval$ = Rx.Observable.timer(0, 1000).map(_ => {
return _ <= defaultTime ? defaultTime - _ : $interval.unsubscribe();
});
function start() {
$interval = interval$.subscribe(_ => {
newTime = _;
console.log(_);
});
}
function pause() {
$interval.unsubscribe();
defaultTime = newTime - 1;
}
document.getElementById('btn').addEventListener('click', start)
document.getElementById('btn2').addEventListener('click', pause)