UNPKG

@ovine/core

Version:

Build flexible admin system with json.

124 lines (123 loc) 3.56 kB
/** * 实现消息通知逻辑 * 解耦组件状态依赖 */ import isArray from 'lodash/isArray'; import isNone from 'lodash/isUndefined'; import { message } from "../constants"; const { storeRoot } = message; let observer = {}; const source = {}; // 格式化存储 key 格式 const storeKeyCtrl = (type, value = '') => { const isStoreKey = value.indexOf(storeRoot) === 0; if (type === 'set') { return isStoreKey ? value : `${storeRoot}${value}`; } return !isStoreKey ? undefined : value.split(storeRoot)[1]; }; // 更改 store 值,就会自动 publish 消息 export const observeStore = new Proxy({}, { get(_, key) { return source[key]; }, // 整个模块的核心逻辑 // 代理object赋值操作,设置值的时候,触发订阅时的回调函数 set(obj, key, value) { // 只有值变化 才触发回调。 if (!(source[key] && source[key] === value)) { // eslint-disable-next-line obj[key] = value; const storeKey = storeKeyCtrl('set', key); if (storeKey && !isNone(observer[storeKey])) { observer[storeKey].forEach((handler) => { handler(value, storeKey); }); } } return true; }, }); // 发送消息 export function publish(key, value) { const msgValue = typeof value === 'undefined' ? {} : value; const keyToObserver = (obsKey) => { const sourceKey = storeKeyCtrl('get', obsKey); if (sourceKey && !isNone(source[sourceKey])) { source[sourceKey] = msgValue; } if (!isNone(observer[obsKey])) { observer[obsKey].forEach((handler) => { handler(msgValue, obsKey); }); } }; if (isArray(key)) { key.forEach(keyToObserver); } else { keyToObserver(key); } } // 取消订阅 export function unsubscribe(key, handler) { const offObserver = (offKey) => { if (!isNone(observer[offKey])) { if (!handler) { observer[offKey] = []; } else { observer[offKey].forEach((obsHandler, index) => { if (obsHandler === handler) { observer[offKey].splice(index, 1); } }); } } }; if (isArray(key)) { key.forEach(offObserver); } else { offObserver(key); } } export function unsubscribeAll() { observer = {}; } // 消息订阅 export function subscribe(key, handler) { const cacheObserverHandlers = (mapKey) => { if (isNone(observer[mapKey])) { observer[mapKey] = []; } observer[mapKey].push(handler); const handlerKey = storeKeyCtrl('get', mapKey); if (handlerKey && !isNone(source[handlerKey])) { handler(source[handlerKey], handlerKey); } }; const listener = { key, unsubscribe: () => { // }, }; if (isArray(key)) { key.forEach(cacheObserverHandlers); listener.unsubscribe = () => key.forEach((k) => unsubscribe(k, handler)); // } else { cacheObserverHandlers(key); listener.unsubscribe = () => unsubscribe(key, handler); } return listener; } // 订阅一次,就销毁 export function subscribeOnce(key, handler) { const listener = subscribe(key, (data) => { handler(data, key); listener.unsubscribe(); }); }