【问题标题】:Session timeout warning popup in AngularAngular中的会话超时警告弹出窗口
【发布时间】:2018-05-15 04:40:06
【问题描述】:

我正在开发一个在 30 分钟不活动后会话超时的应用程序。我有一个新要求,即在用户自动注销前几分钟弹出一条消息,询问用户是否愿意保持会话处于活动状态。

目前,会议以我认为非常非正统的方式进行管理,我需要尝试使用已经存在的内容。应用模块使用了一个名为context.service(作为提供者注入)的服务,它使用 setTimeout 来确定 30 分钟的不活动何时到期。

鉴于我需要访问该倒计时,我想创建一个镜像超时,它会提前 2 分钟执行并触发模式,询问用户是否要保持会话打开。将NgbModal 注入ContextService 后,我收到一个似乎很合理的循环引用错误。尝试使用提供程序在 DOM 上填充模式似乎有点疯狂,但我不确定有什么可行的替代方案。

这是当前状态(存在循环引用错误):

// ...
import { SessionExpirationWarning } from '../components/session-expiration-warning/session-expiration-warning.component';
// ....

constructor(
    private _http: HttpClient,
    private _injector: Injector,
    private modalSvc: NgbModal
) {
    // ...
}

// ...

setSessionTimeout() {
    if (this.appConfig === null) { return; }

    clearTimeout(this._timeoutId);
    clearTimeout(this.timeoutWarning);

    const sessionTimeOutConfig = this.appConfig.SessionTimeoutMinutes;

    const SessionTimeoutMinutes = sessionTimeOutConfig === undefined ? 5 : sessionTimeOutConfig;
    const sessionWarningMinutes = 2;

    this._timeoutId = setTimeout(() => {
        this.sessionExpired();
    }, SessionTimeoutMinutes * (60 * 1000));

    this.timeoutWarning = setTimeout(() => {
        if (!this.warningIsActive) {
            const timeOutWarningModal = this.modalSvc.open(SessionExpirationWarning);

            timeOutWarningModal.result.then((modalResponse) => {
                if (modalResponse === true) {
                    this.keepAlive(null);
                }
            });
        }
    }, sessionWarningMinutes * (60 * 1000));
}

this.timeoutWarning 是我尝试破解一个解决方案。

【问题讨论】:

    标签: javascript angular


    【解决方案1】:

    你可以做的是有一个Observable,在应该显示警告弹出窗口时发出:

    import { timer } from 'rxjs/observable/timer';
    // ...
    public sessionWarningTimer$ = new Subject();
    // ...
    setSessionTimeout() {
        // ...
        timer(sessionWarningMinutes * 60 * 1000).subscribe(this.sessionWarningTimer$);
    }
    

    在一个组件中(例如你的AppComponent)你可以订阅sessionWarningTimer$

    private destroyed$ = new Subject();
    
    ngOnInit() {
        this
            .contextService
            .sessionWarningTimer$
            .takeUntil(this.destroyed$)
            .subscribe(() => this.displaySessionWarning());
    }
    
    ngOnDestroy() {
        this.destroyed$.next();
    }
    
    displaySessionWarning() {
        // your display code here
    }
    

    这样,您可以避免服务中的任何 UI 代码,而是专注于警告逻辑。

    【讨论】:

    • 这看起来是一个很好的答案——正是我正在寻找的方法类型。我的初步测试似乎表明这将按预期工作——将在接下来的几天内进行一些更严格的测试,并在我确认后立即将其标记为正确。再次非常感谢!将探索完全更新会话超时以使用 Observable。
    猜你喜欢
    • 1970-01-01
    • 2013-06-21
    • 2016-02-18
    • 2014-01-16
    • 2018-07-21
    • 2016-05-30
    • 1970-01-01
    • 2012-05-18
    • 1970-01-01
    相关资源
    最近更新 更多