angular - 如何在一段时间后无休止地显示模态?
问题描述
如果用户保持不活动状态,我将尝试在 5 秒后触发模式,并为此编写了一个包含此代码的服务:
public initScreenListen(): void {
this.mergedObservable$ = merge(
fromEvent(document, BanKeyboardEvent.KEY_DOWN),
fromEvent(document, BanMouseEvent.MOUSE_DOWN),
fromEvent(document, BanMouseEvent.MOUSE_MOVE),
fromEvent(document, BanMouseEvent.WHEEL),
fromEvent(document, BanMouseEvent.CLIK),
fromEvent(document, BanMouseEvent.MOUSE_MOVE),
fromEvent(window, BanMouseEvent.MOUSE_MOVE)
);
this.startTimer();
}
public startTimer(): void {
this.createObserable();
console.log('subscription started');
}
public createObserable(): void {
this.ngZone.runOutsideAngular(() => {
this.observeable$ = this.mergedObservable$.pipe(
switchMap((ev) => interval(1000).pipe(take(this.inactivityTime))),
tap((value) => this.isItTimeToShowPopUp(value)),
skipWhile((x) => {
this.timeLapsedSinceInactivity = x;
return x !== this.inactivityTime - 1;
})
);
});
}
public isItTimeToShowPopUp(val: number): void {
this.timeLeftForInactive = this.inactivityTime - val;
if (this.timeLeftForInactive <= 13) {
this.timeLapsedSinceInactivity = this.timeLeftForInactive;
this.ref.tick();
console.log(this.timeLeftForInactive);
}
}
我在组件本身上写了这个:
public ngOnInit(): void {
this.inactivityListenService.initScreenListen();
const subcription = this.inactivityListenService.observeable$.subscribe(
() => {
subcription.unsubscribe();
console.log('here show modal.....');
this.inactivityListenService.initScreenListen();
}
);
}
它只在第一次工作,之后它开始变得混乱。
请你帮我一把好吗?
谢谢。
解决方案
我认为您的实施中有两个问题:
- 你不应该
unsubscribe
从 mainobservable
让它一直工作,那么this.inactivityListenService.initScreenListen()
在显示模态后就不需要再次调用该函数。 - 您应该在函数中使用
filter
而不是,因为在第一次为 false 之后将允许每个发出的值,但将始终过滤每个发出的值并只允许符合给定条件的值。skipWhile
createObserable
skipWhile
filter
返回一个 Observable,只要指定条件成立,它就会跳过源 Observable 发出的所有项目,但一旦条件变为 false,就会发出所有其他源项目。
通过仅发出满足指定谓词的项来过滤源 Observable 发出的项。
以下是应更改的部分代码:
ngOnInit(): void {
this.inactivityListenService.initScreenListen();
this.inactivityListenService.observeable$.subscribe(() => {
// >>>>> You shouldn't unsubscribe here.
console.log('here show modal.....');
// >>>>> There is no need to call initScreenListen again here.
});
}
public createObserable(): void {
this.ngZone.runOutsideAngular(() => {
this.observeable$ = this.mergedObservable$.pipe(
switchMap(ev => interval(1000).pipe(take(this.inactivityTime))),
tap(value => {
this.isItTimeToShowPopUp(value);
}),
// >>>> use `filter` instead of `skipWhile`
filter(x => {
this.timeLapsedSinceInactivity = x;
// >>> reflect the condition after using `filter`
return x === this.inactivityTime - 1;
})
);
});
}
这是一个有效的stackblitz
推荐阅读
- java - 无法加载配置 application.properties
- python - 我想在 ibm cloud 中创建一个具有公共访问权限的存储桶。任何人都应该能够访问它?
- microservices - QLDB 是否与发件箱模式兼容?
- algorithm - 修改的最小生成树
- eventhandler - 无后端事件处理程序
- javascript - 如何消除 JavaScript 中的重复元素(包括自身)?
- yaml - yaml 中的云形成模板如何检查导出的堆栈是否存在(使用嵌套?堆栈)
- reactjs - 反应服务器端数据表
- azure - 无法将文件从 ADLS 移动到雪花
- php - 如何在 PHP 中替换 JSON 上的匹配对象?