在Angular 5中正确订阅Singleton服务
我需要一个计时器被重置,这将在每次活动后调用。因此,我创建了一个TimerService,并在其中设置了计时器 TimerService类:在Angular 5中正确订阅Singleton服务,angular,singleton,angular5,angular2-observables,Angular,Singleton,Angular5,Angular2 Observables,我需要一个计时器被重置,这将在每次活动后调用。因此,我创建了一个TimerService,并在其中设置了计时器 TimerService类: @Injectable() export class TimerService { timer: Observable<any>; constructor() { } setTimer(timerVal: number) { this.timer = Observable.timer(timerVal); } }
@Injectable()
export class TimerService {
timer: Observable<any>;
constructor() { }
setTimer(timerVal: number) {
this.timer = Observable.timer(timerVal);
}
}
现在,我尝试从另一个组件更新计时器的值,但它不会影响已设置的计时器
另一个组件类别:
export class AppComponent implements OnInit{
title = 'DataBox';
constructor(private timerService: TimerService){}
ngOnInit() {
this.timerService.setTimer(3000);
this.timerService.timer.subscribe(t => {
alert("hello");
})
}
}
export class AnotherComponent implements OnInit{
users: Observable<any>;
constructor(private listUser: ListUserService, private timerService: TimerService) { }
ngOnInit() {
}
updateTimer() {
this.timerService.setTimer(5000);
}
}
导出类另一个组件实现OnInit{
用户:可观察;
构造函数(私有listUser:ListUserService,私有timerService:timerService){}
恩戈尼尼特(){
}
updateTimer(){
this.timerService.setTimer(5000);
}
}
如何订阅timerService并随时更新计时器?
如何创建单例服务并订阅计时器?
但它应该只在计时器过期时发出警报,并且只发出一次警报。
我是Angular的新手,所以请容忍我。问题是,在您的服务中,您没有用
设置计时器重置计时器,而是创建一个新的计时器。另一个组件上的订阅仍然存在于一个可观察的组件上,该组件仍然是“活动的”。您唯一更改的是计时器
引用,因此任何新订阅都将订阅新订阅,但旧订阅仍然存在
您要做的是,在过度定义时停止第一个计时器,然后设置新的计时器。但这只能解决问题的前半部分:您的订阅仍在侦听并等待计时器。因此,您必须重新定义应用程序逻辑,以“结束”计时器,或者简单地从计时器中取消订阅
要了解如何停止可观察计时器,请阅读。基本上,您需要先在每个订阅中取消订阅()
,然后重新订阅。我将使用不同的可观察对象(例如“alertWhenNewTimerIsSet()”或其他内容)实现这一点,然后使用subscription
s本身重新订阅新值
诸如此类:
timerservice.ts:
timer: Observable<any>;
renewSubscriptionsAlert: new EventEmitter<any>();
setTimer(timerVal: number) {
timer.renewSubscriptionsAlert.emit(true);
this.timer = Observable.timer(timerVal);
}
顺便说一下,如果你只是需要一个计时器,你也可以使用这个方法 ForestG是正确的,您的根本错误是忽略了javaScript引用 首先,正如ForestG所说,如果您正在寻找的是一个简单的间隔,那么请使用javasScript本机间隔和clearInterval方法 如果您只想运行一个计时器,那么这是您服务中更优雅的解决方案。它通过“takeUntil”操作符创建了一个新的可观察的间隔,该间隔具有条件取消
cancelTimer$ = new Subject();
startTimer(interval?: number = 1000) {
this.cancelTimer$.next();
const timer = Observable.interval(interval);
timer.takeUntil(this.cancelTimer$)
.subscribe((res) => {
console.log(res)
},
err => console.log(err),
() => {
console.log('completed')
})
}
takeUnitl的优点是,我使可观察对象抛出一个“完整”事件,而simple.unsubscribe()则没有。
通过这种方式,您可以添加一个回调来处理前一个计时器。我刚刚了解到,您询问的是计时器,而不是间隔。但是上面的代码应该对双方都适用。请告诉我们是否有任何答案适合您。
cancelTimer$ = new Subject();
startTimer(interval?: number = 1000) {
this.cancelTimer$.next();
const timer = Observable.interval(interval);
timer.takeUntil(this.cancelTimer$)
.subscribe((res) => {
console.log(res)
},
err => console.log(err),
() => {
console.log('completed')
})
}