PigeonJs
是一个轻量级自定义事件或观察者模式的实现。
特点:
- 小巧,不依赖任何
lib
- 单例模式实现,任意地方可添加订阅,移除订阅,清除事件类型;
- 支持单事件触发和群组触发,单事件移除和群组移除;
- 移除订阅只需通过
namespace
命令空间,因为有时添加订阅和移除阅订不在一个作用域下, 这样会带来极大的方便; - 安全的
handlers
事件存储,不会被无意中覆盖;
NameSpace格式:
type.key
: type
为事件的类型,表示群组;key
为订阅的唯一标识符
注意:不支持多层命名空间(例如:uxdc.haleywang.age),第二层后面的部分会被忽略掉
源码:
/**
* pigeon.js
*
* Release 1.2.0
* @author <a href="mailto:harley.wang.vip@gmail.com">Harley Wang</a>
* @describe 一个轻量级自定义事件或观察者模式的实现。
*/
(function(global, factory) {
'use strict';
if (typeof exports === "object" && exports) {
factory(exports); // CommonJS
} else if (typeof define === "function" && define.amd) {
define(['exports'], factory); // AMD
} else {
factory(global.PigeonJs = {}); // <script>
}
}(window, function(PigeonJs) {
'use strict';
var handlers = {};
var splitStr = function(ns){
var values = ns.split('.', 2);
return {'type':values[0], 'key':values[1]};
},
clearHandlers = function(type){
delete handlers[type];
};
/**
* 添加事件
* @param {String} namespace 命名空间,格式必须为:type.key
* @param {Function} handler 触发函数
*/
PigeonJs.addHandler = function(namespace, handler){
var ns = splitStr(namespace);
if(typeof handlers[ns.type] == 'undefined'){
handlers[ns.type] = [];
}else{
this.removeHandler(namespace);
}
handlers[ns.type].push( {'unique':ns.key, 'handler':handler} );
};
/**
* 移除事件
* @param {string} namespace 命名空间,为:type.key 或 type
*/
PigeonJs.removeHandler = function(namespace){
var ns = splitStr(namespace);
if(ns.type && !ns.key){
clearHandlers(ns.type);
}
else if(handlers[ns.type] instanceof Array){
var events = handlers[ns.type];
for(var i=0,len=events.length; i<len; i++){
if(events[i]['unique'] == ns.key){
events.splice(i, 1);
break;
}
}
if(events.length == 0){
clearHandlers(ns.type);
}
}
};
/**
* 触发器
* @param {string} namespace 命名空间,格式为:type.key 或 type
* @param {Object|Array|String|Boolean|Number|Function} data 要传递的数据,可选
*/
PigeonJs.trigger = function(namespace, data){
var ns = splitStr(namespace);
if(handlers[ ns.type ] instanceof Array){
var events = handlers[ns.type];
for(var i=0,len=events.length; i<len; i++){
if(ns.key){
if(events[i]['unique'] == ns.key){
events[i]['handler'](ns, data);
break;
}
}else{
events[i]['handler'](ns, data);
}
}
}
};
}));
Example:
// 添加订阅
PigeonJs.addHandler('uxdc.haleywang', function(ns, event){
console.log(ns, event.message, '我是haleywang,收到!');
});
// 添加订阅
PigeonJs.addHandler('uxdc.ice', function(ns, event){
console.log(ns, event.message, '我是ice,收到!');
});
// 添加订阅
PigeonJs.addHandler('uxdc.ouyi', function(ns, event){
console.log(ns, event.message, '我是ouyi,收到!');
});
// 触发
PigeonJs.trigger('uxdc.ouyi', {message:"2:00 来duang2会议室开会!"});
PigeonJs.trigger('uxdc.haleywang', {message:"4:00 上线!"});
PigeonJs.trigger('uxdc.ice', {message:"带个早点上楼!"});
// 触发群组
PigeonJs.trigger('uxdc', {message:"@all:明天放假一天!"});
// 移除订阅
PigeonJs.removeHandler('uxdc.haleywang');
// 触发群组
PigeonJs.trigger('uxdc', {message:"@all:写周报!"});
// 移除群组
PigeonJs.removeHandler('uxdc');
在React中使用:
使用 PigeonJs
在组件之间进行通讯或数据共享:
// 快捷菜单
var ShortcutMenu = React.createClass({
getInitialState: function() {
return {selected: this.props.selected};
},
show: function(){
this.refs.shortcut_menu.style.display = 'block';
},
hide: function(){
this.refs.shortcut_menu.style.display = 'none';
},
componentDidMount: function(){
var that = this;
PigeonJs.addHandler('ShortcutMenu.onShow', function(ns, event){
that.show();
});
},
componentWillUnmount: function(){
PigeonJs.removeHandler('ShortcutMenu.onShow');
},
render: function() {
return (
<div ref="shortcut_menu" className="shortcut_menu"></div>
);
}
});
ReactDOM.render(<ShortcutMenu />, document.getElementById('shortcut_menu'));
在其它组件中触发:
// 更多快捷菜单
onMore: function(e){
PigeonJs.trigger('ShortcutMenu.onShow');
}