Angular中通知徽标计数管理方案咨询
技术方案:Angular通知面板计数更新(无WebSocket)
一、后端层设计(数据库+API)
- 通知表新增
is_read布尔字段,默认值为false,用于标记通知是否已读 - 提供3个核心API接口:
GET /api/notifications/unread-count:返回当前用户未读通知总数,用于快速更新徽标GET /api/notifications:获取当前用户通知列表,支持?unread=true参数筛选未读通知PUT /api/notifications/mark-read:批量标记通知为已读,支持传ids数组指定单个通知,或传all=true标记所有未读通知
二、Angular前端实现
1. 封装通知服务
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class NotificationService { constructor(private http: HttpClient) {} // 获取未读计数 getUnreadCount(): Observable<number> { return this.http.get<number>('/api/notifications/unread-count'); } // 获取通知列表 getNotifications(unreadOnly = false): Observable<any[]> { return this.http.get<any[]>(`/api/notifications?unread=${unreadOnly}`); } // 标记通知为已读 markAsRead(notificationIds?: number[], markAll = false): Observable<void> { const payload = notificationIds ? { ids: notificationIds } : { all: markAll }; return this.http.put<void>('/api/notifications/mark-read', payload); } }
2. 通知面板组件逻辑
import { Component, OnInit } from '@angular/core'; import { NotificationService } from './notification.service'; @Component({ selector: 'app-notification-panel', templateUrl: './notification-panel.component.html', styleUrls: ['./notification-panel.component.css'] }) export class NotificationPanelComponent implements OnInit { unreadCount = 0; notifications: any[] = []; panelOpen = false; constructor(private notificationService: NotificationService) {} ngOnInit(): void { this.loadUnreadCount(); } // 加载未读计数 loadUnreadCount(): void { this.notificationService.getUnreadCount().subscribe(count => { this.unreadCount = count; }); } // 打开通知面板 openPanel(): void { this.panelOpen = true; // 获取通知列表并标记所有未读为已读 this.notificationService.getNotifications(true).subscribe(unReads => { const ids = unReads.map(n => n.id); this.notificationService.markAsRead(ids).subscribe(() => { this.loadUnreadCount(); }); }); // 拉取全量通知展示 this.notificationService.getNotifications().subscribe(notifications => { this.notifications = notifications; }); } // 单个通知标记已读 markSingleRead(notificationId: number): void { this.notificationService.markAsRead([notificationId]).subscribe(() => { this.loadUnreadCount(); // 本地更新状态,避免重复请求 const target = this.notifications.find(n => n.id === notificationId); if (target) target.is_read = true; }); } }
3. 徽标样式与模板
CSS样式:
.notification-icon { position: relative; cursor: pointer; } .notification-badge { position: absolute; top: -6px; right: -6px; background: #ff4d4f; color: #fff; border-radius: 50%; width: 18px; height: 18px; display: flex; align-items: center; justify-content: center; font-size: 11px; display: none; } .notification-badge.show { display: flex; } .notification-item.unread { background-color: #f5f5f5; font-weight: 500; }
组件模板:
<div class="notification-icon" (click)="openPanel()"> <i class="fa fa-bell"></i> <span class="notification-badge" [class.show]="unreadCount > 0">{{ unreadCount }}</span> </div> <div class="notification-panel" *ngIf="panelOpen"> <div *ngFor="let item of notifications" class="notification-item" [class.unread]="!item.is_read" (click)="markSingleRead(item.id)"> {{ item.title }} <p>{{ item.content }}</p> </div> </div>
三、优化建议
- 定时刷新:在通知服务中添加定时器(比如每30秒)调用
getUnreadCount,提升计数实时性 - 本地缓存:将未读计数存入
localStorage,标记已读后同步更新缓存,减少不必要的API请求 - 请求防抖:如果用户频繁操作面板,对标记已读的请求做防抖处理,避免重复提交
内容的提问来源于stack exchange,提问作者JSLover
相关产品推荐
相关产品推荐

