观察者模式定义了一种依赖关系,解决了主体对象和观察者之间功能的耦合,主要应用于大型项目的模块化开发中,解决团队开发中模块之间的通信问题,利用观察者模式还可以实现自定义事件。
//观察者
var Observer=(function(){
var _messages={};
return{
//注册消息接口
register:function(type,fn){
if(typeof _messages[type]==="undefined"){
_messages[type]=[fn];
}else{
_messages[type].push(fn);
}
},
//发布消息接口
fire:function(type,args){
if(!_messages[type]){
return;
}
var event={
type:type,
args:args||{}
},
i=0;
len=_messages[type].length;
for(;i<len;i++){
_messages[type][i].call(this,event);
}
},
//移除消息接口
remove:function(type,fn){
if(_messages[type] instanceof Array){
var i=_messages[type].length-1;
for(;i>=0;i--){
_messages[type][i]===fn && _messages[type].splice(i,1);
}
}
}
};
})();
简单使用:
var fn1=function(e){
console.log("I am "+e.type);
};
var fn2=function(e){
console.log(e.type,e.args.msg);
};
Observer.register("test",fn1);
Observer.register("test",fn2);
Observer.fire('test',{msg:"传递参数"});//I am test test 传递参数
Observer.remove('test',fn1);
Observer.fire("test",{msg:"删除了一个test事件"})
实例:
实现提交消息后,在ul中插入一条消息,点击删除按钮,删除该消息,更改消息的数量。
共有<span id="msg_num">0</span>条消息
<ul id="msg">
</ul>
<textarea id="user_text"></textarea>
<button id="user_submit">提交</button>
(function(){
//追加一则消息
function addMsgItem(e){
var text=e.args.text,
li=document.createElement("li"),
button=document.createElement("button");
li.innerHTML=text;
button.innerHTML="删除";
button.onclick=function(){
document.getElementById("msg").removeChild(li);
Observer.fire("removeMsg",{num:-1});
};
li.appendChild(button);
document.getElementById("msg").appendChild(li);
}
Observer.register("addMsg",addMsgItem);
})();
(function(){
//更改消息的数目
function changeMsgNum(e){
var num=e.args.num;
var omsgNum=document.getElementById("msg_num");
omsgNum.innerHTML=parseInt(omsgNum.innerHTML)+num;
}
Observer.register("addMsg",changeMsgNum);
Observer.register("removeMsg",changeMsgNum);
})();
(function(){
//用户点击提交按钮
document.getElementById("user_submit").onclick=function(){
var text=document.getElementById("user_text").value;
if(text===''){
return;
}
document.getElementById("user_text").value='';
Observer.fire("addMsg",{text:text,num:1});
};
})();