4

我在我的 Angular 应用程序中实现了一个会话超时模块,它监控空闲时间并打开会话超时对话框并在对话框上显示倒计时值。问题是当我在该屏幕上移动鼠标或至少触摸该屏幕时,倒计时值停止,但我只想在我单击对话框而不是屏幕上的任何内容时才停止对话框上的倒计时值。我认为如果我们提供自定义中断,如下面的链接所示,可以做到这一点

例如,如果我只配置鼠标单击,它可以停止对话框上的倒计时,但这不会发生。可能是这个问题可能是因为我正在从另一个组件打开会话超时对话框。

但我无法停止倒计时,这是我的示例代码

this.idle.onIdleStart.subscribe(() => {
  console.log('on idle start');
  let dialogRef;

  if (this.dialogRef === undefined || this.dialogRef === null) {

    dialogRef = this.dialog['open'](SessionTimeoutDialogComponent, {
      width: '30%',
      data: {idleTime: 10, timeoutTime: 10},
      panelClass: 'session-timeout-dialog'
    });
    this.dialogRef = dialogRef;
  }

  this.dialogRef.afterClosed().subscribe(result => {
    this.timeoutTime = result;
  });
  this.dialogRef = dialogRef;
});


 this.idle.onTimeoutWarning.subscribe((countdown) => {
  this.timeoutTime = countdown;
  this.dataService.changeVersionSelectionData(countdown);

});

谁能指导我们如何做到这一点?

4

1 回答 1

7

解决方案: 诀窍是,idleStart通过调用清除中断this.idle.clearInterrupts(),这会删除事件侦听器,但实际倒计时仍在进行,可以根据对话中的用户操作重置或结束,

这是我所做的:

    this.idle.onIdleStart.subscribe(() => {
      console.log('空闲启动');

      this.idle.clearInterrupts();

      常量 dialogConfig = new MatDialogConfig();
      dialogConfig.disableClose = true;
      dialogConfig.data = {标题,正文};

      常量 dialogRef = this.dialog.open(DialogComponent, dialogConfig);

      dialogRef.afterClosed().subscribe(result => {
        console.log('对话框关闭。Result='+result);
        如果(结果)
          this.idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
          this.idle.watch();
        });
        this.dialogRef = dialogRef;
        返回 dialogRef.afterClosed();
      }
    });

    this.idle.onTimeoutWarning.subscribe((倒计时) => {
      this.dialogRef.componentInstance.body='您将在'+countdown+'秒!';
    });

    this.idle.onTimeout.subscribe(() => {
      console.log('超时..');
      this.dialogRef.close();
      this.logout();
      this.router.navigate(['/']);
    });

这个想法是clearInterrupts()在空闲开始之后,因此不会捕获任何事件。

然后,您打开对话框并在其中idle.setTimeout(period)看到倒计时。现在,假设你有一个dialog.component.html


    <h1 mat-dialog-title>{{ title }}</h1>
    <div mat-dialog-content>
        <p>{{ body }}</p>
    </div>
    <div mat-dialog-actions style="text-align: center;">
        <button mat-button (click)="close()">STAY LOGGED</button>
    </div>

和一个dialog.component.ts

    @零件({
        选择器:'应用程序对话框',
        templateUrl: './dialog.component.html',
    })
    导出类 DialogComponent 实现 OnInit {
        标题:字符串;
        正文:字符串;

        构造函数(
            公共 dialogRef:MatDialogRef,
            @Inject(MAT_DIALOG_DATA) 公共数据:{title, body}) {

            this.title = 数据.title;
            this.body = 数据.body;
        }

        关() {
            this.dialogRef.close(true);
        }
    }

在此设置中,如果单击按钮:“保持记录”,则使用 退出对话框result=true。您重置计时器并重新开始观看空闲。

如果您不单击该按钮,您最终将被注销。

这是我在长时间试验 MatDialog 并实时更新其内容(用于倒计时)后得到的。

在我看来,这项工作已经完成了!

于 2020-01-19T21:35:06.257 回答