Angular 如何在每次成功登录时多次实例化ng2空闲

Angular 如何在每次成功登录时多次实例化ng2空闲,angular,ng-idle,Angular,Ng Idle,我有一个问题,我将空闲设置为在会话到期前一分钟显示一个弹出窗口。然后会话超时或用户注销。用户下次登录时,如果出现超时,他们现在有2个弹出窗口。用户注销并再次登录,现在有3个弹出窗口,依此类推。当用户注销时,如何销毁Idle的当前实例 我的设置如下: constructor(private idle: Idle, ...) {} ngOnInit() { this.setIdle(); } private setIdle() { // Client activity timeo

我有一个问题,我将空闲设置为在会话到期前一分钟显示一个弹出窗口。然后会话超时或用户注销。用户下次登录时,如果出现超时,他们现在有2个弹出窗口。用户注销并再次登录,现在有3个弹出窗口,依此类推。当用户注销时,如何销毁Idle的当前实例

我的设置如下:

constructor(private idle: Idle, ...) {}

ngOnInit() {
    this.setIdle();
}

private setIdle() {
    // Client activity timeout. 29 minutes to 'idle', 1 minute beyond that to timeout
    this.ngZone.runOutsideAngular(() => {
        // this.idle.setIdle(29 * 60);
        // this.idle.setTimeout(1 * 60);
        this.idle.setIdle(10);
        this.idle.setTimeout(10);
        this.idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
    });


    this.idle.onTimeout.subscribe(() => {
        this.ngZone.run(() => {
            this.errorDialogRef.close();
            sessionStorage.setItem('sessionExpired', 'true');
            this.displayErrorModal(true);
        });

    });

    this.idle.onIdleStart.subscribe(() => {
        this.ngZone.run(() => {
            this.displayIdleWarning();
        });
    });

    this.ngZone.runOutsideAngular(() => {
        this.idle.watch();
    });
}
在注销过程中,我尝试了
this.idle.stop()
删除this.idle
。但两者都不起作用

仅供参考:它必须运行在角度区域之外,否则我们的量角器测试会中断

更新: 在找到将数组归零的解决方案之前,我一直在尝试:

this.idle.onTimeout.unsubscribe();
this.idle.onIdleStart.unsubscribe();
this.idle.onIdleEnd.unsubscribe();
但这只会在随后的登录过程中导致以下错误:

core.es5.js?0445:1084 ERROR Error: Uncaught (in promise): ObjectUnsubscribedError: object unsubscribed 

在我看来,我的组件保留着它的引用,或者在注销过程中没有被破坏。

我能够检查
这个.idle
对象,并发现“do stuff”对象(
onTimeout
onIdleStart
onIdleEnd
onInterrupt
,以及
onTimeoutWarning
)他们是事件的始作俑者。每一个都有一个叫做
观察者
的对象<代码>观察者
是观察者的数组。每次创建一个新的弹出窗口时,我都注意到数组增加了。因此,在注销过程中,我刚刚清除了观察员:

this.idle.stop();
this.idle.onTimeout.observers.length = 0;
this.idle.onIdleStart.observers.length = 0;
this.idle.onIdleEnd.observers.length = 0;

这可能不是最好的办法。我相信有更好的方法从EventEmitter中删除观察者。但是我找不到它,这是一种快速而肮脏的方法

我认为取消订阅观察员的正确方法是使用订阅变量订阅,而不是将观察员数组长度设置为0。你问题中的代码几乎是正确的。你尝试的是:

this.idle.onTimeout.unsubscribe();
这将结束this.idle.onTimeout对this.idle.onTimeout订阅的可观察对象的订阅(这就是为什么会出现ObjectUnsubscribedError错误)

本应有效的方法如下:

private idleOnTimeout$: Subscription;

// Subscribe in for example ngOnInit()
this.idleOnTimeout$ = this.idle.onTimeout.subscribe();

// Unsubscribe on ngOnDestroy()
this.idleOnTimeout$.unsubscribe();

ng idle的示例代码没有涵盖这一点,因为在他们的示例中,ng idle存在于应用程序的主要组件中,除非您完全重新加载页面(这也会重置ng idle),否则该组件将永远不会被破坏

这真的很有效!非常感谢您让我开心。如果要在本文中提到的代码中包含这些行,我将不胜感激,如果您有其他解决方案,我将不胜感激。先谢谢你