如何使用Angular 2 Alert(Toaster)设置超时自动关闭提示消息
Angular Alert 提示自动关闭问题解决方案
我看了你的alert服务代码,发现几个可能导致超时自动关闭不生效的点,比如路由变化逻辑和超时逻辑的冲突、没有管理定时器导致多提示冲突,还有没法自定义超时时长。下面给你调整后的完整方案:
问题分析
- 当你设置
alerting=true时,路由变化的逻辑只会把this.alerts设为false,不会立刻清空提示,这会和超时关闭的逻辑冲突 - 没有存储定时器ID,多个提示同时触发时,定时器会互相干扰
- 当前超时时间固定为3秒,没法自定义成你想要的4秒或其他时长
修改后的Alert Service代码
import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; import { Router, NavigationStart } from '@angular/router'; @Injectable({ providedIn: 'root' }) export class AlertService { private subject = new Subject<any>(); private alerts = false; // 用来管理超时定时器,避免冲突 private timeoutId: any; constructor(private router: Router) { // 路由变化时处理提示和定时器 router.events.subscribe(event => { if (event instanceof NavigationStart) { // 先清除未执行的超时定时器 if (this.timeoutId) { clearTimeout(this.timeoutId); this.timeoutId = null; } if (this.alerts) { this.alerts = false; } else { // 清空当前提示 this.subject.next(); } } }); } private alertMessage(message: string, alerting = false, type: string, timeout = 4000) { this.alerts = alerting; window.scrollTo(0, 0); this.subject.next({ type: type, msg: message }); // 如果设置了超时时间,启动自动关闭 if (timeout > 0) { // 先清除之前的定时器,防止多个提示叠加时出错 if (this.timeoutId) { clearTimeout(this.timeoutId); } this.timeoutId = setTimeout(() => { this.subject.next(); this.alerts = false; this.timeoutId = null; }, timeout); } } // 成功提示,支持自定义是否保留到路由变化、自定义超时 public success(message: string, alerting = false, timeout = 4000) { this.alertMessage(message, alerting, 'success', timeout); } // 可以同理添加错误、信息等提示方法 public error(message: string, alerting = false, timeout = 4000) { this.alertMessage(message, alerting, 'error', timeout); } // 手动关闭提示的方法 public clear() { if (this.timeoutId) { clearTimeout(this.timeoutId); this.timeoutId = null; } this.subject.next(); this.alerts = false; } // 返回可观察对象给组件订阅 public getAlert() { return this.subject.asObservable(); } }
关键修改点说明
- 新增
timeoutId管理定时器:避免多个提示同时触发时,定时器互相干扰,而且路由变化时能及时清除未执行的定时器 - 支持自定义超时:默认4秒,调用时可以传参修改(比如
this.alertService.success('操作成功', false, 5000)就是5秒后关闭) - 同步更新状态:超时关闭时不仅清空提示,还重置
this.alerts,避免和路由变化的逻辑冲突 - 新增手动关闭方法:方便用户点击关闭按钮时主动清除提示
组件端订阅示例(AlertComponent)
确保你的提示组件正确订阅服务的消息,比如:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs'; import { AlertService } from './alert.service'; @Component({ selector: 'app-alert', templateUrl: './alert.component.html' }) export class AlertComponent implements OnInit, OnDestroy { private alertSubscription: Subscription; currentAlert: any; constructor(public alertService: AlertService) { } ngOnInit() { this.alertSubscription = this.alertService.getAlert().subscribe(alert => { this.currentAlert = alert; }); } ngOnDestroy() { // 组件销毁时取消订阅,防止内存泄漏 this.alertSubscription.unsubscribe(); } }
提示组件模板示例
<div *ngIf="currentAlert" class="alert alert-{{currentAlert.type}} alert-dismissible fade show" role="alert"> {{currentAlert.msg}} <button type="button" class="btn-close" (click)="alertService.clear()" aria-label="Close"></button> </div>
这样调整后,你的提示消息就能按照设定的时长自动关闭,也支持自定义超时时间,同时不会和路由变化的逻辑冲突啦~
内容的提问来源于stack exchange,提问作者T M
相关产品推荐
相关产品推荐

