UNPKG

okam-core

Version:

The extension for small program framework

186 lines (159 loc) 4.4 kB
/** * @file Make component support broadcast ability * @author sparklewhy@gmail.com */ 'use strict'; /* eslint-disable fecs-export-on-declare */ import {normalizeExtendProp} from '../../helper/methods'; import eventCenter from '../../helper/eventCenter'; const ONCE_LISTEN_REGEXP = /^(.*)\.once$/; const broadcastAPIs = { /** * Send broadcast event * * @param {...any} args the broadcast args */ $broadcast(...args) { eventCenter.emit.apply(eventCenter, args); }, /** * Listen broadcast event * * @param {string} eventName the event name to broadcast * @param {Function} handler the listen handler * @param {boolean=} isOnce whether is once listen, optional, by default false */ $onBroadcast(eventName, handler, isOnce) { let bindEvents = this._bindBroadcastEvents; if (!bindEvents) { bindEvents = this._bindBroadcastEvents = []; } bindEvents.push([eventName, handler]); if (isOnce) { eventCenter.once(eventName, handler); } else { eventCenter.on(eventName, handler); } }, /** * Remove broadcast event listener * * @param {string} eventName the event to remove * @param {Function} handler the handler to remove */ $offBroadcast(eventName, handler) { eventCenter.off(eventName, handler); }, /** * Bind the declaration broadcast events * * @param {Object} events the broadcast events to listen * @private */ __bindBroadcastEvents(events) { if (!events) { return; } let bindEvents = this._bindBroadcastEvents; /* istanbul ignore next */ if (!bindEvents) { bindEvents = this._bindBroadcastEvents = []; } Object.keys(events).forEach(k => { let result = ONCE_LISTEN_REGEXP.exec(k); let eventName = result ? result[1] : k; let handler = events[k].bind(this); bindEvents.push([eventName, handler]); if (result) { eventCenter.once(eventName, handler); } else { eventCenter.on(eventName, handler); } }); this._bindBroadcastEvents = bindEvents; }, /** * Remove the bind broadcast events * * @private */ __removeBroadcastEventListeners() { let bindEvents = this._bindBroadcastEvents; /* istanbul ignore next */ if (!bindEvents) { return; } bindEvents.forEach(item => eventCenter.off(item[0], item[1])); this._bindBroadcastEvents = []; }, /** * init 'broadcastEvent' and 'eventHub' event * * @private */ __initEvents() { if (this.__hasInitEvents) { return; } this.__hasInitEvents = true; this.$eventHub = eventCenter; let events = this.$rawBroadcastEvents; if (typeof events === 'function') { events = this.$rawBroadcastEvents = events(); } this.__bindBroadcastEvents(events); } }; export default { app: Object.assign({ /** * The hook when app launch * * @private */ onLaunch() { this.$eventHub = eventCenter; this.__bindBroadcastEvents(this.broadcastEvents); } }, broadcastAPIs), component: { /** * The instance initialization before the instance is normalized and created. * * @param {boolean} isPage whether is page component * @private */ $init(isPage) { normalizeExtendProp( this, 'broadcastEvents', '$rawBroadcastEvents', isPage ); }, /** * The hook when page onInit * * @private */ onInit() { this.__initEvents(); }, /** * The hook when component created * * @private */ created() { this.__initEvents(); }, /** * The hook when component detached * * @private */ detached() { this.__removeBroadcastEventListeners(); }, methods: broadcastAPIs } };