我需要重置一个计时器,它将在每次活动后调用。所以我创建了一个 TimerService 并在其中设置了计时器。
TimerService类:
@Injectable()
export class TimerService {
timer: Observable<any>;
constructor() { }
setTimer(timerVal: number) {
this.timer = Observable.timer(timerVal);
}
}
然后我尝试订阅它,一旦计时器失效,它应该发出警告。我把这个逻辑放在AppComponent中,因为我需要在Rootlevel中订阅它。
AppComponent类:
export class AppComponent implements OnInit{
title = 'DataBox';
constructor(private timerService: TimerService){}
ngOnInit() {
this.timerService.setTimer(3000);
this.timerService.timer.subscribe(t => {
alert("hello");
})
}
}
现在我尝试从另一个组件更新计时器的值,但它不会影响已经设置的计时器。
AnotherComponent类:
export class AnotherComponent implements OnInit{
users: Observable<any>;
constructor(private listUser: ListUserService, private timerService: TimerService) { }
ngOnInit() {
}
updateTimer() {
this.timerService.setTimer(5000);
}
}
我如何订阅timerService并随时更新计时器? 如何创建Singleton服务并订阅计时器? 但它应该只在计时器到期时才发出警报并且只发出一次。 我是Angular的新手,所以请耐心等待。
答案 0 :(得分:1)
ForestG是正确的,你的基本错误是忽略javaScript引用。
首先,正如ForestG所说,如果它是您正在寻找的简单间隔,请使用javasScript本地间隔和clearInterval方法。
如果您只想运行一个计时器,那么这是您服务中更优雅的解决方案。它通过&#34; takeUntil&#34;创建一个新的区间可观察到条件取消。操作
var xml = '<?xml version="1.0" encoding="UTF-8"?><root><city><ID>1</ID><Name>Kabul</Name><CountryCode>AFG</CountryCode><District>Kabol</District><Population>1780000</Population></city><city><ID>2</ID><Name>Qandahar</Name><CountryCode>AFG</CountryCode><District>Qandahar</District><Population>237500</Population></city><city><ID>3</ID><Name>Herat</Name><CountryCode>AFG</CountryCode><District>Herat</District><Population>186800</Population></city></root>';
var parser = new DOMParser();
// Parse the xml
var parsedXML = parser.parseFromString(xml, 'text/xml');
// Now get the elements
var id = parsedXML.getElementsByTagName('ID');
var Name = parsedXML.getElementsByTagName('Name');
var countryCode = parsedXML.getElementsByTagName('CountryCode');
var district = parsedXML.getElementsByTagName('District');
var population = parsedXML.getElementsByTagName('Population');
// Get the tag names; because getElementsByTagName returns an array like HTMLCollection, we need to loop through the results like we would with an array
for (var i = 0; i < id.length; i++) {
console.log(id[i].tagName + " " + Name[i].tagName+ " " + countryCode[i].tagName + " "+ district[i].tagName + " "+ population[i].tagName);
}
takeUnitl的优点是我使observable抛出一个&#34;完成&#34;事件,简单&#34; .unsubscribe()&#34;才不是。 这样你就可以添加一个回调来处理前一个计时器。
答案 1 :(得分:0)
问题是,在您的服务中,您不会使用setTimer
重置计时器,而是创建一个新计时器。另一个组件的订阅仍然存在于Observable上,它仍然是#34; alive&#34;。您唯一更改的是timer
引用,因此任何新的子核心都将订阅新的子核心 - 但旧的订阅仍然存在。
您要做的是,在过度定义时停止第一个计时器,然后设置新计时器。但这只能解决问题的前半部分:你的子语言仍然在监听并等待计时器。所以你必须重新定义你的应用程序逻辑,以及#34;完成&#34;定时器,或者,简单地从它们中取消。
要了解如何停止可观察的计时器,请阅读this question。基本上,您需要先{strong> 每次订阅 unsubscribe()
,然后重新订阅。我会用不同的observable(例如&#34; alertWhenNewTimerIsSet()&#34;或其他东西)来实现,然后使用subscription
s本身重新订阅新值。
timer: Observable<any>;
renewSubscriptionsAlert: new EventEmitter<any>();
setTimer(timerVal: number) {
timer.renewSubscriptionsAlert.emit(true);
this.timer = Observable.timer(timerVal);
}
并在您的组件中:
mySubscription: any;
ngOnInit() {
this.timerService.setTimer(3000);
this.mySubscription = this.timerService.timer.subscribe(t => {
alert("hello");
});
this.timerService.renewSubscriptionsAlert(alert => {
myTimerServiceSubscription.unsubscribe();
this.mySubscription = this.timerService.timer.subscribe(t => {
alert("hello");
});
}
顺便说一下,如果你只是需要一个计时器,你也可以使用window.setTimeout()方法。