angular中全局订阅事件,包含取消订阅,非常好用

Posted munergs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了angular中全局订阅事件,包含取消订阅,非常好用相关的知识,希望对你有一定的参考价值。

import { Injectable } from \'@angular/core\';
import { Subject } from \'rxjs\';

@Injectable({ providedIn: \'root\' })
export class GlobalEvent {
  /**存储事件上一次的value */
  private _datas = {};
  private _data$ = new Subject<EventInfo>();
  private _dataFlow$ = this._data$.asObservable();
  private _subscriptions: Map<GlEvenName, { [id: string]: Function[] }> = new Map();

  constructor() {
    this._dataFlow$.subscribe((data: EventInfo) => this._onEvent(data));
  }

  /**
   * 通知构造函数中的订阅触发事件
   * @param 事件名
   * @param 数据
   */
  notifyDataChanged<T>(event: GlEvenName, value: T) {
    let current = this._datas[event];
    if (current !== value) {
      this._datas[event] = value;
      this._data$.next({
        event: event,
        data: value
      });
    }
  }

  /**
   * 订阅事件
   * @param 事件名
   * @param 回调函数id用于移除监听 推荐使用
   * @param 回调函数
   */
  subscribe(event: GlEvenName, id: string = \'global\', callback: Function) {
    let subscriber = this._subscriptions.get(event) || Object.create(null);
    let cbs = subscriber[id] = subscriber[id] || [];
    cbs.push(callback);
    this._subscriptions.set(event, subscriber);
  }

  /**
  * 移除订阅事件
  * @param 事件名
  * @param 回调函数id用于移除
  */
  unsubscribe(event: GlEvenName, id: string = \'global\') {
    let subscriber = this._subscriptions.get(event) || Object.create(null);
    delete subscriber[id]
  }

  /**触发事件回调函数 */
  private _onEvent(evenInfo: EventInfo) {
    let subscriber = this._subscriptions.get(evenInfo.event) || Object.create(null);
    let data = evenInfo.data;
    for (const key in subscriber) {
      let cbs = subscriber[key] || [];
      cbs.forEach(cb => {
        cb.call(null, data)
      })
    }
  }
}

type GlEvenName = keyof typeof ONNAME;
/**事件名 和  数据 */
interface EventInfo { event: GlEvenName, data: any };


/**全局gl事件名称集合,键值必须一样 必须在此处调用并写入GlEvenName */
export const ONNAME = {
  CHNGE: \'CHNGE\',
  GOOD: \'GOOD\',
}

使用方法就是在需要用到的组件中的构造函数中引入

import { GlobalEvent } from \'src/app/globalnew.state\';
constructor(
   private gl$:GlobalEvent
){}
------
this.gl$.notifyDataChanged(\'CHNGE\',\'123456\')

在需要订阅的组件中

import { GlobalEvent } from \'src/app/globalnew.state\';
constructor(
   private gl$:GlobalEvent
){}
------
this.gl$.subscribe(\'CHNGE\',\'CHNGE\',((item:any)=>{
 console.log(item) //打印出\'123456\'
}))

this.gl$.unsubscribe(\'CHNGE\',\'CHNGE\');//取消订阅

以上是关于angular中全局订阅事件,包含取消订阅,非常好用的主要内容,如果未能解决你的问题,请参考以下文章

如何在Stripe PHP和webhook中使用好事件,比较收到的付款数量并取消订阅

如何取消订阅使用 lambda 表达式的事件?

如何取消订阅使用 lambda 表达式的事件?

(十五)Vue3.x中我们将采用mitt实现全局事件总成

我应该取消订阅根 Angular 组件中的 observables 吗?

Angular 2 - 订阅 FormControl 的 valueChanges 是不是需要取消订阅?