Angular 带rxjs定时器的角度服务。。。需要主题吗?
我想实现一个全局下拉超时,用户可以将鼠标从下拉列表中移出,然后再回到下拉列表中,以防止它消失。我正在为此使用服务,但我不确定如何实现计时器 服务:Angular 带rxjs定时器的角度服务。。。需要主题吗?,angular,rxjs,Angular,Rxjs,我想实现一个全局下拉超时,用户可以将鼠标从下拉列表中移出,然后再回到下拉列表中,以防止它消失。我正在为此使用服务,但我不确定如何实现计时器 服务: 从'@angular/core'导入{Injectable}; 从“rxjs”导入{Observable,timer}; @可注射({providedIn:'root'}) 导出类DropTimerService{ dropHide$=新的可观察(); 构造函数(){} startTimer():void{ console.log('启动计时器')
从'@angular/core'导入{Injectable};
从“rxjs”导入{Observable,timer};
@可注射({providedIn:'root'})
导出类DropTimerService{
dropHide$=新的可观察();
构造函数(){}
startTimer():void{
console.log('启动计时器')
this.dropHide$=计时器(3000);
}
stopTimer():void{
console.log('停止计时器')
this.dropHide$=新可观察();
}
}
启动和停止功能正在运行;控制台日志报告正确,但未触发对observable的订阅
this.dropSub=this.dropTimer.dropHide$.subscribe(事件=>{
console.log(事件)
this.dropClass='';
})
我想我需要一个主题
和。下一步
计时器上的主题,但我不确定。我还需要在用户将鼠标移回下拉列表时停止计时器,并希望能够使计时器在命令下立即过期(当用户打开其他下拉列表时,任何其他人都应收到关闭信号)
我觉得我可以用一些
setTimeout
s来实现这一点,它可以为主题。下一步
,但我也觉得可能有一种纯粹的rxjs方法来实现这一点。上面编写的服务代码中的问题是,dropHide$
成员变量将分配给新的可观察的
实例。如果它获得了一个新实例,以前的订阅就会丢失。这就是为什么会发生以下情况:
dropHide$
使用dropHide$=new Observable()获取默认的Observable
实例代码>
在具有subscribe
的组件中,我们订阅其事件
当调用startTimer()
时,this.dropHide$=timer(3000)
将一个新的INSACE分配给dropHide$
,因此以前的subscribe
的回调将永远不会被调用
Observable
没有订阅,并且Observable
是惰性的,因此事件永远不会触发服务
中,我们存储订阅
,并在需要启动计时器时订阅。subscribe获取一个回调函数,该函数可以在计时器完成时调用。如果计时器被取消,我们只需取消订阅订阅
。这样,服务
代码如下所示:
import { Injectable } from "@angular/core";
import { Subscription, timer } from "rxjs";
@Injectable({ providedIn: "root" })
export class DropTimerService {
private timerSubscription: Subscription;
constructor() {}
startTimer(timerDone: Function) {
console.log("Starting the timer");
this.timerSubscription = timer(3000).subscribe(event => {
timerDone();
});
}
stopTimer(): void {
console.log("Timer stopped");
this.timerSubscription.unsubscribe();
}
}
组件模板示例:
<p>
Use the buttons to start/cancel the timer.
</p>
<button (click)="onStartClick()">Start</button>
<button (click)="onStopClick()">Cancel</button>
要测试并使用它,这里有stackblitz
代码:
这几乎是我所需要的,但当我打开一个新的下拉列表时,它无法关闭所有其他下拉列表。目前,如果我打开一个新的,没有过期的旧的将保持打开状态,并且永远不会关闭,直到我将鼠标移入和移出它们。这就是为什么我认为我需要订阅一个主题,以便让下拉列表知道何时应该关闭。^通过在服务中添加一个主题来解决此问题,只需在每次勾选时关闭所有主题。
import { Component } from "@angular/core";
import { DropTimerService } from "./drop-timer.service";
@Component({
selector: "my-app",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
name = "Angular";
constructor(private dropTimerService: DropTimerService) {}
onStartClick() {
function TimerFinishedCallback() {
console.log("Timer finished!");
}
this.dropTimerService.startTimer(TimerFinishedCallback);
}
onStopClick() {
this.dropTimerService.stopTimer();
}
}