@ng-idle/core:一个空闲实例上发生的超时导致中断在另一个空闲实例上停止工作

问题描述 投票:0回答:1

我正在使用 "@ng-idle/core": "~11.1.0" 和 Angular 13 应用程序。

我有两个空闲实例,一个用于自动注销,另一个用于屏幕保护程序。

如果我的屏幕保护程序处于“活动”状态,并且第一次发生超时(即自动注销),并且如果我尝试中断屏幕,则屏幕保护程序不会关闭并且会阻塞 UI。(有一点很清楚,中断在这种情况下订阅将停止工作)。

如何解决这个问题?.

示例代码供参考:

import {Component, NgZone, OnInit} from '@angular/core';
import {DEFAULT_INTERRUPTSOURCES, Idle, LocalStorage, LocalStorageExpiry} from '@ng-idle/core';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit{
  title = 'my-idle-app';
  private readonly screenSaver!: HTMLElement;
  private readonly screenSaverText!: Text;
  idleTime1: number = 1;
  private screenSaverIdle = new Idle(new LocalStorageExpiry(new LocalStorage()), this.ngZone);

  constructor(readonly ngZone: NgZone, private idle1: Idle) {
    this.screenSaver = document.createElement('div');
    this.screenSaver.id = 'screensaver';
    this.screenSaver.className = 'screen-saver';
    this.screenSaverText = document.createTextNode('---%');
    const movingTxt = document.createElement('span');
    movingTxt.appendChild(this.screenSaverText);
    this.screenSaver.appendChild(movingTxt);
    this.removeScreenSaver();

    this.screenSaverIdle.setIdleName('screenSaverIdleService');
    this.screenSaverIdle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
    this.screenSaverIdle.setTimeout(false);
    this.screenSaverIdle.setIdle(10);
    this.screenSaverIdle.watch();

    this.screenSaverIdle.onIdleStart.subscribe(() => {
      document.body.appendChild(this.screenSaver);
    });

    this.screenSaverIdle.onIdleEnd.subscribe(() => {
      console.log('IDLE END ::');
      this.removeScreenSaver();
    });
  }

  ngOnInit() {
    this.idle1.setIdleName('AutoLogoutIdleService');
    this.idle1.setInterrupts(DEFAULT_INTERRUPTSOURCES);

    this.idle1.setIdle(this.idleTime1);
    this.idle1.setTimeout(10);

    this.idle1.onIdleStart.subscribe(() => {
      console.log("IDLE 1 STARTS")
    });

    this.idle1.onIdleEnd.subscribe({
      next: () => {
        console.log("IDLE 1 END");
      },
      complete: () => {
        console.log("idle 1 completed");
      }
    });

    this.idle1.onTimeout.subscribe(()=> {
      console.log("User session timed Out",);
    });

    this.idle1.watch();
  }

  private removeScreenSaver() {
    const ex = document.getElementById('screensaver');
    if (ex) {
      document.body.removeChild(ex);
    }
  }
}

我分析了 ng-idle 库的源代码,看起来,由于屏幕保护程序理想实例的超时值为“false”,因此它不应该取消中断订阅。

所以,我的问题是关于正在创建的服务的实例。这里有什么问题吗?.

javascript reactjs angular typescript ng-idle
1个回答
0
投票

查看源代码很难暂停/重置ng-idle2的计时器。所以我只是停止并启动屏幕保护程序计时器,这似乎工作正常。

this.idle1.onTimeout.subscribe(() => {
  console.log('User session timed Out');
  this.removeScreenSaver();
  this.screenSaverIdle.stop();
  this.screenSaverIdle.watch();
});

完整代码:

import { Component, NgZone, OnInit } from '@angular/core';
import {
  DEFAULT_INTERRUPTSOURCES,
  Idle,
  LocalStorage,
  LocalStorageExpiry,
} from '@ng-idle/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
  title = 'my-idle-app';
  private readonly screenSaver!: HTMLElement;
  private readonly screenSaverText!: Text;
  idleTime1: number = 1;
  private screenSaverIdle = new Idle(
    new LocalStorageExpiry(new LocalStorage()),
    this.ngZone
  );

  constructor(readonly ngZone: NgZone, private idle1: Idle) {
    this.screenSaver = document.createElement('div');
    this.screenSaver.id = 'screensaver';
    this.screenSaver.className = 'screen-saver';
    this.screenSaverText = document.createTextNode('---%');
    const movingTxt = document.createElement('span');
    movingTxt.appendChild(this.screenSaverText);
    this.screenSaver.appendChild(movingTxt);
    this.removeScreenSaver();

    this.screenSaverIdle.setIdleName('screenSaverIdleService');
    this.screenSaverIdle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
    this.screenSaverIdle.setTimeout(false);
    this.screenSaverIdle.setIdle(10);
    this.screenSaverIdle.watch();
    this.screenSaverIdle.onIdleStart.subscribe(() => {
      console.log(
        `Screen saver Active:: ${this.screenSaverIdle.getIdle()}::${this.screenSaverIdle.getTimeout()}::${this.screenSaverIdle.isIdling()}::${this.screenSaverIdle.isRunning()}`
      );
      document.body.appendChild(this.screenSaver);
    });

    this.screenSaverIdle.onIdleEnd.subscribe(() => {
      console.log('Screen saver Idle end ::');
      this.removeScreenSaver();
    });
  }

  ngOnInit() {
    this.idle1.setIdleName('AutoLogoutIdleService');
    this.idle1.setInterrupts(DEFAULT_INTERRUPTSOURCES);

    this.idle1.setIdle(this.idleTime1);
    this.idle1.setTimeout(30);

    this.idle1.onIdleStart.subscribe(() => {
      console.log('IDLE 1 STARTS');
    });

    this.idle1.onIdleEnd.subscribe({
      next: () => {
        console.log('IDLE 1 END');
      },
      complete: () => {
        console.log('idle 1 completed');
      },
    });

    this.idle1.onTimeout.subscribe(() => {
      console.log('User session timed Out');
      this.removeScreenSaver();
      this.screenSaverIdle.stop();
      this.screenSaverIdle.watch();
    });

    this.idle1.watch();
  }

  private removeScreenSaver() {
    const ex = document.getElementById('screensaver');
    console.log(ex);
    if (ex) {
      document.body.removeChild(ex);
    }
  }
}

Stackblitz 演示

© www.soinside.com 2019 - 2024. All rights reserved.