【问题标题】:Angular material Snackbar: not overwriting previous message with new messageAngular Material Snackbar:不使用新消息覆盖以前的消息
【发布时间】:2023-03-17 15:01:01
【问题描述】:

我正在使用 Snackbar 向用户显示错误和警告消息。有时这些可能在时间上彼此接近,比第一条消息的显示持续时间更接近。如此接近,以至于用户在用第二条消息覆盖之前没有足够的时间阅读第一条消息。

有没有办法将行为更改为在显示第二条消息之前等待第一条消息结束,或者将它们堆积起来?

【问题讨论】:

    标签: angular angular-material angular7


    【解决方案1】:

    您可以将所有消息放入一个数组中,以模拟消息的“队列”,而不是为每条消息调用 Snackbar。我建议有一个服务来负责处理这个问题。

    然后,在此服务中,您可以订阅 Snackbar 的 afterDismissed() 回调,该回调将在 Snackbar 关闭时触发。下面是一个简单的例子:

    messageQueue: string[] = [
    'Message 1',
    'Message 2',
    'Message 3'
    ]
    
    private displaySnackbar(): void {
      const nextMessage = this.getNextMessage();
    
      if(!nextMessage){
        return;
      }
    
      this.snackBar.open(nextMessage, undefined, { duration: 1000 })
      .afterDismissed()
      .subscribe(() => {
        this.displaySnackbar();
      });
    }
    
    private getNextMessage(): string | undefined {
      return this.messageQueue.length ? this.messageQueue.shift() : undefined;
    }
    

    编辑:

    为了避免任何混淆,在我提供的示例中,我不建议直接调用displaySnackbar()(因此private 可见范围)。相反,这是我公开它的方式(您可以在下面的 Stackblitz 演示中看到):

    addMessage(message: string): void {
      this.messageQueue.push(message);
    
      if(!this.processingMessage) {
        this.displaySnackbar();
      }
    }
    

    这仅取决于processingMessage 标志来确定它是否应该调用displaySnackbar() 方法。当然我们还需要设置这个标志,所以这里是更新的displaySnackbar()

    private displaySnackbar(): void {
      const nextMessage = this.getNextMessage();
    
      if(!nextMessage){
        this.processingMessage = false; // No message in the queue, set flag false
        return;
      }
    
      this.processingMessage = true; // A message was dequeued and is being processed
    
      this.snackBar.open(nextMessage, undefined, { duration: 1000 })
      .afterDismissed()
      .subscribe(() => {
        this.displaySnackbar();
      });
    }
    

    Here 是基本的、可运行的 Stackblitz 演示。

    在演示中,您将看到您可以“垃圾邮件单击”“添加消息”按钮,该按钮会将所有创建的消息排队,但 Snackbar 只会在每条消息完成显示后显示它们1 秒。

    【讨论】:

    • 感谢您的工作示例,我确实在考虑将所有这些都打包到自己的服务中,因为我预计在未来的项目中会重用。再次感谢。
    • 这真的有效吗?你什么时候开始第一次触发通知?您不是每次都重新初始化订阅吗?在这种配置中,这不可能在生产中正常工作。
    • 是的,它确实有效,帖子中的 Stackblitz 示例应该表明了这一点。 afterDismissed 订阅是一次性可观察的(类似于 http get),因此事后不会留下任何订阅。 “在这种配置中,这不可能……”到底是怎么回事?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-21
    • 1970-01-01
    • 2014-08-01
    • 2012-08-17
    • 1970-01-01
    • 1970-01-01
    • 2020-04-16
    相关资源
    最近更新 更多