角材料 Snackbar:不会用新消息覆盖以前的消息 [英] Angular material Snackbar: not overwriting previous message with new message

查看:22
本文介绍了角材料 Snackbar:不会用新消息覆盖以前的消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using a Snackbar to display error and warning messages to the user. Sometimes these can happen close to each other in time, closer than the display duration time of the first message. So close that it does not give enough time to the user to read the first message before overwriting with the second message.

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

Is there a way of changing the behaviour to waiting for the end of the first message before displaying the second, or piling them up?

推荐答案

不是为每条消息调用 Snackbar,您可以将它们全部放入一个数组中以模拟消息队列".我建议有一个负责处理这个问题的服务.

Instead of invoking the Snackbar for each message, you could put all of them into an array to mimic a 'queue' of messages. I would suggest having a service which is responsible for handling this.

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

Then, in this service you can subscribe to the Snackbar's afterDismissed() callback which will fire whenever the Snackbar closes. Here's a simple example of what that would look like:

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 演示中所见):

So as to avoid any confusion, in the example I have provided I do not recommend calling displaySnackbar() directly (hence the private visibility scope). Instead, here's how I have exposed it (as you can see in the Stackblitz demo from below):

addMessage(message: string): void {
  this.messageQueue.push(message);

  if(!this.processingMessage) {
    this.displaySnackbar();
  }
}

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

This just depends on the processingMessage flag to determine whether or not it should invoke the displaySnackbar() method. Of course we will also need to set this flag so here's the updated 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();
  });
}

这里是基本的、有效的 Stackblitz 演示.

Here is the basic, working Stackblitz demo.

在演示中,您将看到您可以垃圾邮件点击"添加消息"按钮,该按钮会将所有创建的消息排入队列,但 Snackbar 只会在每条消息显示完毕后显示它们1 秒.

In the demo, you will see that you can 'spam click' the 'Add Message' button which will queue up all of the messages that get created, but the Snackbar will only display them once each message has finished being displayed for 1 second.

这篇关于角材料 Snackbar:不会用新消息覆盖以前的消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆