Observer中,一个对象(subject)维持一系列依赖于它(观察者)的对象,12bet,将有关状态的任何变更自动通知给它们。当不再希望某个特定的观察者获得其注册目标发出的通知时,12bet,该目标可将它从观察者列表中删除。Observer包括如下组件:
每一个Subject应当维护一个观察者列表,用于添加、12博体育,删除或通知观察它的所有观察者,要维护这个观察者列表,12博体育,自然需要实现一些基础方法,比如CRUD操作等:
//构造函数
function ObserverList() {
this.observerList = [];
}
//向观察者列表中增加观察者对象
ObserverList.prototype.add = function(obj) {
return this.observerList.push(obj);
};
//清空观察者列表
ObserverList.prototype.empty = function() {
this.observerList = [];
};
//统计观察者列表中的观察者数量
ObserverList.prototype.count = function() {
return this.observerList.length;
};
//根据序号获取观察者对象
ObserverList.prototype.get = function(index) {
if (index >= 0 && index < this.observerList.length) {
return this.observerList[index];
}
};
//获取某个观察者对象在列表中的序号
ObserverList.prototype.indexOf = function(obj) {
return this.observerList.indexOf(obj);
};
//从观察者列表中移除某个观察者对象
ObserverList.prototype.remove = function(obj) {
var index = this.get(obj);
if (index != -1) {
this.removeAt(index);
}
};
//从观察者列表中移除某个特定序号的观察者对象
ObserverList.prototype.removeAt = function(index) {
if (index >= 0 && index < this.observerList.length) {
this.observerList.splice(index, 1);
}
};
目标主要就是操作这个观察者列表,以及使用这个观察者列表通知观察者:
//Subject构造函数
function Subject() {
this.observers = new ObserverList();
}
//给这个Subject增加观察者
Subject.prototype.addObserver = function(observer) {
this.observers.add(observer);
};
//从这个Subject移除观察者
Subject.prototype.removeObserver = function(observer) {
this.observers.remove(observer);
};
//通知观察者列表中的所有观察者
Subject.prototype.notify = function(context) {
var observerCount = this.observers.count();
for (var i = 0; i < observerCount; i++) {
this.observers.get(i).update(context);
}
};
由于Subject中通知观察者需要调用观察者的update方法,所以Observer中只要实现了update方法就行了:
function Observer() {
this.update = function(context) {
console.log(context);
};
}
我们可以通过给DOM元素扩展的方式来将DOM节点构造成一个Subject对象,首先实现一个扩展方法:
function extend(obj, extension) {
for (var key in extension) {
obj[key] = extension[key];
}
}
比如这里有如下HTML:
<input type="text" id="ipt"/>
<button id="btn">点击</button>
在点击按钮之后,会将input框中的内容传递给所有观察者。首先需要将按钮扩展成Subject对象,并在其点击事件触发时通知观察者,通知内容为input的内容:
var $btn = document.getElementById("btn");
var $ipt = document.getElementById("ipt");
extend($btn, new Subject());
$btn.onclick = function(event){
this.notify($ipt.value);
event.stopPropagation();
};
这样按钮就是一个Subject对象了,我们可以新建几个观察者,并加入到这个Subject对象的观察者列表当中:
var observer1 = new Observer();
observer1.update = function(context){
console.log("observer1 is notified," + context);
};
var observer2 = new Observer();
observer2.update = function(context){
console.log("observer2 is notified," + context);
};
$btn.addObserver(observer1);
$btn.addObserver(observer2);
我们在input框中输入内容后,点击按钮,两个观察者将会获得input框的内容:
observer1 is notified,superlin
observer2 is notified,superlin
observer1 is notified,流星
observer2 is notified,流星