You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular Material Snackbar点击onAction后无法显示后续提示框

Angular Material MatSnackBar 点击Action后二次弹窗不显示问题

问题描述

在Angular应用中使用Angular Material的MatSnackBar实现通知功能,预期用户点击第一个提示框的action按钮时,触发第二个提示框显示。但实际调试发现,onAction()订阅内的代码已执行(showFinalSnackBar()被调用),但第二个提示框未在页面显示。

简化代码:

if(validPhotosIds.length > 0) {
    // 业务代码
} else {
    const snackBarRef = await this.snackBar.show({
      message: "itemUpdated",
      actionMessage: "undo",
    })
    snackBarRef.onAction().subscribe(() => {
      this.showFinalSnackBar()
    })
    this.showFinalSnackBar()
    this.selectOperationCompletedEmitter.next()
}

已确认信息:

  • showFinalSnackBar()方法已正常调用(控制台日志验证)
  • 浏览器控制台无报错
  • SnackBar服务在应用其他场景运行正常

原因分析

Angular Material的MatSnackBar默认采用单例模式,同一时间仅允许显示一个SnackBar。当点击第一个SnackBar的action按钮时,第一个SnackBar处于关闭过渡状态,此时尝试打开第二个SnackBar会被默认配置拦截,导致无法显示。

解决方案

方案1:等待第一个SnackBar完全关闭后再打开第二个

通过订阅第一个SnackBar的afterDismissed()方法,确保其完全关闭后再触发第二个弹窗:

snackBarRef.onAction().subscribe(() => {
  snackBarRef.afterDismissed().subscribe(() => {
    this.showFinalSnackBar()
  })
})

方案2:配置SnackBar为队列模式

修改SnackBar的全局或局部配置,允许多个SnackBar堆叠显示:

局部配置(在showFinalSnackBar方法中)

showFinalSnackBar() {
  this.snackBar.open('操作已撤销', '确认', {
    duration: 3000,
    maxStack: 2, // 允许最多2个SnackBar堆叠
    politeness: 'assertive'
  })
}

全局配置(在AppModule中)

import { MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material/snack-bar';

@NgModule({
  providers: [
    {
      provide: MAT_SNACK_BAR_DEFAULT_OPTIONS,
      useValue: { maxStack: 2, politeness: 'assertive' }
    }
  ]
})
export class AppModule { }

方案3:主动关闭第一个SnackBar后延迟打开第二个

手动关闭第一个SnackBar,短暂延迟后再打开第二个,确保DOM完成更新:

snackBarRef.onAction().subscribe(() => {
  snackBarRef.dismiss();
  setTimeout(() => {
    this.showFinalSnackBar();
  }, 100); // 100ms延迟确保第一个弹窗已完全移除
})

内容的提问来源于stack exchange,提问作者Heisenberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 03:35:11