发布主体类:
function Subject() { this.observers = new ObserverList(); }
发布主体类原型上面的一些方法:
// 移除观察者对象 Subject.prototype.removeObserver = function (ob) { this.observers.removeAt(this.observers.indexOf(ob)) }
// 移除观察者对象 Subject.prototype.removeObserver = function (ob) { this.observers.removeAt(this.observers.indexOf(ob)) }// 通知观察者更新 Subject.prototype.notify = function (value) { let count = this.observers.count(); while (count-- > 0) { this.observers.get(count).update(value); } }
声明一个ObserverList类, 目的是将subject和内部维护的observes功能分离开来
function ObserverList() { this.oberverList = [] } // 向oberverList数组中添加 ObserverList.prototype.add = function (ob) { this.oberverList.push(ob); } // 返回oberverList的数组的长度 ObserverList.prototype.count = function () { return this.oberverList.length; } // 返回oberverList中某个对象的下标 ObserverList.prototype.indexOf = function (ob) { return this.oberverList.indexOf(ob); } // 通过index获取oberverList中的某个对象 ObserverList.prototype.get = function (index) { return this.oberverList[index]; } // 移除oberverList中的某个对象 ObserverList.prototype.removeAt = function (index) { this.oberverList.splice(index, 1); }
观察者类
function Observer() { } // 更新的方法 Observer.prototype.update = function () { console.log('更新') }
将发布类和观察者类绑定到DOM元素上,这样就可以通过在DOM元素上使用类的方法了!
浅合并方法
function extend(obj, origin){
for(let key in origin){
obj[key] = origin[key]
}
return obj;
}
给发布按钮合并上发布类的方法
extend(addObserveBtn, new Subject());
给发布按钮绑定事件:
// 给按钮绑定事件(添加观察对象) addObserveBtn.onclick = function () { // 添加新 observer let observerDiv = document.createElement("div"); let input = document.createElement("input"); let span = document.createElement("span"); span.innerHTML = 'observer ' + uid++; input.setAttribute('type', 'checkbox'); // 添加到页面上 observerDiv.appendChild(input) observerDiv.appendChild(span) oberverList.appendChild(observerDiv); // 合并 Observer的方法 extend(input, new Observer()); // 重写update方法 input.update = function (value) { this.checked = value; } // 注册observer this.addObserver(input); }
给发布按钮绑定事件
// 发布事件,让所有观察者收到消息后更新 subBtn.onclick = function () { addObserveBtn.notify(this.checked) }
最后展示一下DOM结构(其实上面的三个雷才是核心,DOM只是为了更好的将观察者模式的核心机制形象的展示出来)
<body> <div class="control"> <button id="addObserverBtn">添加订阅者</button> <input type="checkbox" id="subBtn"> <span>发布事件</span> </div> <div class="oberverList"> <div> <!-- <input type="checkbox"> <span>observer1</span> --> </div> </div></body>