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');// 勾销订阅