push.js与Angular集成:服务封装与依赖注入

push.js与Angular集成:服务封装与依赖注入

【免费下载链接】push.js The world's most versatile desktop notifications framework :earth_americas: 【免费下载链接】push.js 项目地址: https://gitcode.com/gh_mirrors/pu/push.js

你还在为Angular应用中的桌面通知管理感到困扰吗?本文将详细介绍如何将push.js(GitHub 加速计划 / pu / push.js)与Angular框架无缝集成,通过服务封装和依赖注入实现优雅的通知管理方案。读完本文,你将掌握:push.js核心API封装、Angular服务设计模式、依赖注入最佳实践以及跨浏览器通知适配方案。

push.js核心能力解析

push.js作为一款跨平台通知框架,其核心类Push.js提供了创建、管理和关闭桌面通知的完整生命周期支持。该类通过Permission.js处理浏览器通知权限请求,同时集成了多种通知代理(Agent)以支持不同浏览器环境:

// 多浏览器代理支持 [src/push/Push.js#L50-L56]
this._agents = {
  desktop: new DesktopAgent(win),
  chrome: new MobileChromeAgent(win),
  firefox: new MobileFirefoxAgent(win),
  ms: new MSAgent(win),
  webkit: new WebKitAgent(win)
};

框架的核心能力包括:

  • 自动检测浏览器环境并选择最佳通知实现
  • 统一的通知生命周期管理(创建/关闭/自动过期)
  • 服务 worker 集成支持后台通知
  • 权限请求与状态管理

Angular服务封装方案

基础服务封装

创建PushNotificationService封装push.js核心功能,通过Angular依赖注入系统提供全局访问点:

// src/app/services/push-notification.service.ts
import { Injectable } from '@angular/core';
import Push from 'push.js/src/push/Push';
import Permission from 'push.js/src/push/Permission';

@Injectable({ providedIn: 'root' })
export class PushNotificationService {
  private pushInstance: Push;
  
  constructor() {
    this.pushInstance = new Push(window);
    // 配置服务工作器路径 [src/push/Push.js#L58-L61]
    this.pushInstance.config({
      serviceWorker: '/assets/serviceWorker.min.js'
    });
  }
  
  // 检查浏览器支持状态 [src/push/Push.js#L370-L378]
  isSupported(): boolean {
    return this.pushInstance.supported();
  }
  
  // 请求通知权限 [src/push/Permission.js#L89-L132]
  async requestPermission(): Promise<boolean> {
    if (!this.pushInstance.Permission.has()) {
      try {
        await this.pushInstance.Permission.request();
        return true;
      } catch {
        return false;
      }
    }
    return true;
  }
  
  // 创建通知 [src/push/Push.js#L283-L314]
  async showNotification(title: string, options: any): Promise<void> {
    if (!await this.requestPermission()) {
      throw new Error('通知权限被拒绝');
    }
    
    return this.pushInstance.create(title, {
      body: options.body,
      icon: options.icon || '/assets/icons/notification.png',
      timeout: options.timeout || 5000,
      onClick: options.onClick
    });
  }
  
  // 清除所有通知 [src/push/Push.js#L355-L364]
  clearAll(): boolean {
    return this.pushInstance.clear();
  }
}

高级功能封装

扩展服务以支持通知分组、历史记录和自定义事件:

// 通知分组管理
private notificationGroups: Map<string, Array<{id: string, title: string}>> = new Map();

async showGroupedNotification(groupKey: string, title: string, options: any) {
  const notification = await this.showNotification(title, options);
  const group = this.notificationGroups.get(groupKey) || [];
  
  group.push({
    id: Date.now().toString(),
    title
  });
  
  this.notificationGroups.set(groupKey, group);
  return notification;
}

// 获取分组通知历史
getGroupHistory(groupKey: string): Array<{id: string, title: string}> {
  return this.notificationGroups.get(groupKey) || [];
}

依赖注入与模块配置

根模块集成

在AppModule中配置通知服务,并注册全局错误处理:

// src/app/app.module.ts
import { NgModule, ErrorHandler } from '@angular/core';
import { PushNotificationService } from './services/push-notification.service';

class NotificationErrorHandler implements ErrorHandler {
  constructor(private pushService: PushNotificationService) {}
  
  handleError(error: any): void {
    this.pushService.showNotification('应用错误', {
      body: error.message || '发生未知错误',
      icon: '/assets/icons/error.png'
    });
    console.error(error);
  }
}

@NgModule({
  providers: [
    PushNotificationService,
    { provide: ErrorHandler, useClass: NotificationErrorHandler }
  ]
})
export class AppModule { }

组件中使用

在组件中注入并使用通知服务:

// src/app/components/dashboard/dashboard.component.ts
import { Component, OnInit } from '@angular/core';
import { PushNotificationService } from '../../services/push-notification.service';

@Component({
  selector: 'app-dashboard',
  template: `
    <button (click)="sendNotification()">发送通知</button>
    <div *ngIf="!isSupported">您的浏览器不支持桌面通知</div>
  `
})
export class DashboardComponent implements OnInit {
  isSupported = false;
  
  constructor(private notificationService: PushNotificationService) {}
  
  ngOnInit() {
    this.isSupported = this.notificationService.isSupported();
  }
  
  async sendNotification() {
    try {
      await this.notificationService.showNotification('新消息', {
        body: '您有3条未读消息',
        icon: '/assets/icons/message.png',
        timeout: 10000,
        onClick: () => window.focus()
      });
    } catch (e) {
      console.error('通知发送失败', e);
    }
  }
}

高级集成策略

服务工作器配置

为支持后台通知,需配置service worker并在Angular应用中注册:

// src/app/services/push-notification.service.ts
async registerServiceWorker() {
  if ('serviceWorker' in navigator) {
    try {
      await navigator.serviceWorker.register(
        this.pushInstance.config().serviceWorker,
        { scope: '/' }
      );
      console.log('服务工作器注册成功');
    } catch (error) {
      console.error('服务工作器注册失败:', error);
    }
  }
}

通知权限状态管理

结合Angular Router实现基于路由的权限控制:

// 路由守卫中检查权限
@Injectable()
export class NotificationGuard implements CanActivate {
  constructor(
    private notificationService: PushNotificationService,
    private router: Router
  ) {}
  
  async canActivate(): Promise<boolean> {
    const hasPermission = await this.notificationService.requestPermission();
    if (!hasPermission) {
      this.router.navigate(['/notification-permission-guide']);
      return false;
    }
    return true;
  }
}

常见问题解决方案

跨浏览器兼容性处理

push.js已内置多浏览器适配,但在Angular应用中仍需注意:

  1. Safari兼容性:确保在index.html中添加权限提示:

    <meta name="apple-mobile-web-app-capable" content="yes">
    
  2. 服务工作器作用域:Angular CLI默认输出路径可能需要调整service worker位置:

    // angular.json
    "assets": [
      "src/assets",
      { "glob": "serviceWorker.min.js", "input": "node_modules/push.js/dist/", "output": "/" }
    ]
    

构建优化

使用Angular的tree-shaking优化push.js引入大小:

// 仅导入所需模块
import Push from 'push.js/src/push/Push';
import { DesktopAgent } from 'push.js/src/agents/DesktopAgent';

总结与最佳实践

通过服务封装与依赖注入,我们实现了push.js与Angular的优雅集成。关键最佳实践包括:

  1. 单一职责:通知服务专注于通知管理,避免业务逻辑混入
  2. 错误边界:通过全局错误处理器捕获并通知异常
  3. 权限管理:在用户交互后请求权限,提升用户体验
  4. 浏览器检测:提前检查支持状态并提供降级方案
  5. 服务工作器:配置后台通知支持以提升应用离线能力

这种集成方案不仅保持了Angular应用的架构清晰,还充分利用了push.js的跨平台优势,为用户提供一致的通知体验。完整实现可参考项目测试用例中的使用示例。

【免费下载链接】push.js The world's most versatile desktop notifications framework :earth_americas: 【免费下载链接】push.js 项目地址: https://gitcode.com/gh_mirrors/pu/push.js

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值