首页 > 解决方案 > 如何在一段时间后无休止地显示模态?

问题描述

如果用户保持不活动状态,我将尝试在 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();
      }
    );
  }

它只在第一次工作,之后它开始变得混乱。

请你帮我一把好吗?

谢谢。

标签: angularrxjs

解决方案


我认为您的实施中有两个问题:

  • 你不应该unsubscribe从 mainobservable让它一直工作,那么this.inactivityListenService.initScreenListen()在显示模态后就不需要再次调用该函数。
  • 您应该在函数中使用filter而不是,因为在第一次为 false 之后将允许每个发出的值,但将始终过滤每个发出的值并只允许符合给定条件的值。skipWhilecreateObserableskipWhilefilter

跳过时:

返回一个 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


推荐阅读