Angular 激活部件上的按钮并继续计数,直到停止
我正在尝试实现一个计时器 我的问题是:我启动计时器,但每当我更改页面时,计时器都会重置/我必须再次启动:( 目标是,当启动计时器时,只有在单击“暂停”时才会停止,如果我单击“启动”并可以更改页面,则计时器始终处于活动状态 有人能帮我吗 我离开下面,我的例子的链接,计时器在服务选项卡中…当我切换到主页并返回服务查看时间时…它被禁用,我希望它始终保持活动状态 htmlAngular 激活部件上的按钮并继续计数,直到停止,angular,typescript,Angular,Typescript,我正在尝试实现一个计时器 我的问题是:我启动计时器,但每当我更改页面时,计时器都会重置/我必须再次启动:( 目标是,当启动计时器时,只有在单击“暂停”时才会停止,如果我单击“启动”并可以更改页面,则计时器始终处于活动状态 有人能帮我吗 我离开下面,我的例子的链接,计时器在服务选项卡中…当我切换到主页并返回服务查看时间时…它被禁用,我希望它始终保持活动状态 html <button (click)='startTimer()'>Start Timer</button> &
<button (click)='startTimer()'>Start Timer</button>
<button (click)='pauseTimer()'>Pause</button>
<p>{{display}}</p>
通过使用服务,您可以在刷新浏览器之前保留数据。我已经检查了您的代码,并在“服务”文件夹中添加了一个帮助服务。请不要混淆服务(即角度服务)和服务(您的组件服务)。 在离开服务组件之前,您需要更新角度服务中的两个变量。一个是计时器是否暂停,另一个是此时的计时器计数。 我们*可以在Ngondestory()服务组件的生命周期钩子中实现这一点 服务组件我们将从角度服务获取过去的信息,并相应地显示计时器 下面是一段代码。 在“服务”文件夹中添加timer.service.ts文件并写入以下代码
import { Injectable, Inject } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class TimerService {
time:number = 0;
timerState:any;
}
将您的服务组件修改为以下内容
import { Component, OnInit, OnDestroy } from '@angular/core';
import {TimerService} from './timer.service';
@Component({
selector: 'app-services',
templateUrl: './services.component.html',
styleUrls: ['./services.component.css']
})
export class ServicesComponent implements OnInit, OnDestroy {
constructor(private timerService: TimerService) { }
ngOnInit() {
this.time = this.timerService.time;
if(this.timerService.timerState === 'visible_on') {
this.startTimer();
} else if(this.timerService.timerState === 'visible_off'){
this.display = this.transform(this.timerService.time);
}
}
interval;
time = 0;
display:any;
startTimer() {
this.interval = setInterval(() => {
if (this.time === 0) {
this.time++;
} else {
this.time++;
}
this.display=this.transform( this.time);
this.timerService.timerState = 'visible_on';
}, 1000);
}
transform(value: number): string {
var sec_num = value;
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
return hours+':'+minutes+':'+seconds;
}
pauseTimer(data,row) {
this.timerService.timerState = 'visible_off';
clearInterval(this.interval);
}
ngOnDestroy() {
this.timerService.time = this.time;
}
}
发生这种情况的原因是,每次在路由之间切换时,组件都会被破坏。现在,当您再次导航到它时,会创建一个新的计时器以及组件的其他部分 要解决此问题,请将计时器间隔的计算委托给单例服务(
TimerService
),并将其注入组件中
timer.service.ts
import { Injectable } from "@angular/core";
@Injectable({
providedIn: "root"
})
export class TimerService {
interval;
time = 0;
display;
startTimer() {
this.interval = setInterval(() => {
if (this.time === 0) {
this.time++;
} else {
this.time++;
}
this.display = this.transform(this.time);
return this.display;
}, 1000);
}
transform(value: number): string {
var sec_num = value;
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - hours * 3600) / 60);
var seconds = sec_num - hours * 3600 - minutes * 60;
return hours + ":" + minutes + ":" + seconds;
}
pauseTimer() {
clearInterval(this.interval);
}
fetchDisplay() {
return this.display;
}
}
services.component.ts
import { Component, OnInit } from "@angular/core";
import { TimerService } from "../timer.service";
@Component({
selector: "app-services",
templateUrl: "./services.component.html",
styleUrls: ["./services.component.css"]
})
export class ServicesComponent implements OnInit {
constructor(private timerService: TimerService) {}
ngOnInit() {}
startTimer() {
this.timerService.startTimer();
}
pauseTimer() {
this.timerService.pauseTimer();
}
}
services.component.html
<h1> Services Component </h1>
<button (click)='startTimer()'>Start Timer</button>
<button (click)='pauseTimer()'>Pause</button>
<p>{{ timerService.fetchDisplay() }}</p>
服务组件
启动计时器
暂停
{{timerService.fetchDisplay()}}
工作之所以发生这种情况,是因为每次在路由之间切换时,组件都会被破坏。请注意,时间仍在运行。由于组件已被破坏,因此该组件不再显示其值。新组件将启动并显示一个新计时器。每次导航出该组件时,都会添加内存和CPU泄漏。请使用一个服务。你可以把你的计时器和计时器逻辑输入到sigleton服务中吗?但我想你希望计时器继续而不是等待?@NicholasK确切地说,我打算让他继续计时。谢谢你帮我这么多忙!我试图暗示这一点,但时间不停了。你能把stackblitz链接放进去吗或者试着编辑我的?可能是我应用得不好:(
<h1> Services Component </h1>
<button (click)='startTimer()'>Start Timer</button>
<button (click)='pauseTimer()'>Pause</button>
<p>{{ timerService.fetchDisplay() }}</p>