观察者模式
当 主体的状态发生了改变 通知先关个体 相关个体的数据也同时发生改变更新
实际项目中,观察者模式需要与 框架中的 双向数据绑定 结合使用
观察者模式使用:
1.需要一个主体 实例化对象
2.需要一个消息盒子 存储所有需要执行的程序
3.on方法:
向消息盒子添加要执行的程序
1.执行的程序有 分类 也就是 事件类型
2.在事件类型,绑定添加 事件处理函数
3.将来这些 事件处理函数,还需要被删除,必须要添加事件处理函数的名称
添加的过程步骤--判断是否有这个类型
如果没有这个类型
创建这个类型,同时,添加事件处理函数
事件处理函数,以数组的形式存储
如果有这个类型
循环遍历,如果没有这个事件处理函数,我们再添加
4.off方法:删除消息盒子中,已经添加的方法
判断 类型是否存在
如果类型不存在
不再执行之后的程序
如果类型存在
循环遍历,如果事件名称存在,执行删除程序
5.emit方法:发布执行消息盒子中的方法
可以执行一个或者多个事件处理函数
而且还要保证,事件处理函数,是已经添加的事件处理函数,才会执行
需要两个参数
第一个参数是: 事件类型
第二个参数是: 所有需要执行的事件处理函数
class Observer{
constructor(){
// 消息盒子
this.msg = {};
}
// 向消息盒子添加要执行的程序
// 参数1,事件类型
// 参数2,事件处理函数的函数名称
on( type , funName ){
// 判断是否有这个类型
if( this.msg[type] === undefined ){
// 证明没有这个 事件类型 是 第一次添加
// 直接向 消息盒子,添加类型,同时以数组的形式,存储事件处理函数名称
this.msg[type] = [funName];
}else{
// 证明有这个 事件类型 不是 第一次添加
// 循环遍历 事件类型 看 事件类型数组中 是否已经有了 事件处理函数名称
// 如果没有,再添加
let bool = true;
// 循环遍历,v就是函数名称
this.msg[type].forEach( v=>{
if(v === funName){
// 存储的函数名称 等于 添加的函数名称
bool = false;
}
} )
// 循环结束,如果bool还是true,证明事件类型数组中,没有要添加的函数名称
if(bool){
this.msg[type].push( funName );
}
}
}
// 删除消息盒子中已经添加的方法
// 参数1:事件类型
// 参数2:事件处理函数名称
off(type,funName){
if(this.msg[type] !== undefined){
// 调用事件类型,不是undefined,证明事件类型存在,再执行程序
this.msg[type].forEach( (v,k)=>{
// 如果 存储的名称 等于 输入的 函数名称
if( v === funName ){
// 数组删除单元,从当前索引开始删除,删除一个单元
this.msg[type].splice( k , 1);
// 没有重复数据,不用考虑数组坍塌的问题
}
} )
}
}
// 执行消息盒子中已经添加的方法
// 参数1:事件类型
// 参数2:所有需要执行的事件处理函数名称
// 使用 ...合并运算符 以数组形式存储
emit(type , ...funName){
// 判断 事件类型 是否存在
if( this.msg[type] !== undefined ){
// v1 存储的函数名称
this.msg[type].forEach( v1 => {
// v2 是 输入的参数,也就是要执行的函数名称
funName.forEach( v2 =>{
// 存储的,和要执行的函数名称,相同,我们才会执行
if( v1 === v2 ){
// 执行发布程序
v1();
}
})
})
}
}
}
// 创建观察者模式主体,实例化对象
const observer = new Observer();
// 通过on方法,添加事件类型和事件处理函数名称
observer.on( 'qing' , qingYeYe);
observer.on( 'qing' , qingNaiNai);
observer.on( 'qing' , qingBaBa);
observer.on( 'qing' , qingMaMa);
observer.on( 'moshou' , moshouPhone);
observer.on( 'moshou' , moshouHeadset);
observer.on( 'moshou' , moshouIpad);
observer.on( 'moshou' , moshouPc);
observer.on( 'jiancha' , jianchaBan);
observer.on( 'jiancha' , jianchaJiao);
observer.on( 'jiancha' , jianchaXiao);
observer.on( 'jiancha' , jianchaJu);
// 通过 off 方法 执行删除
observer.off( 'jiancha' , jianchaJu);
// 通过 emit方法 执行函数
observer.emit( 'jiancha' , jianchaBan , jianchaJiao , jianchaXiao , abc );
// 执行jianchaBan() jianchaJiao() jianchaXiao()方法
// 不执行abc()方法
console.log(observer);
// Observer
// msg:
// jiancha: Array(3)
// 0: ƒ jianchaBan()
// 1: ƒ jianchaJiao()
// 2: ƒ jianchaXiao()
// length: 3
// __proto__: Array(0)
// moshou: Array(4)
// 0: ƒ moshouPhone()
// 1: ƒ moshouHeadset()
// 2: ƒ moshouIpad()
// 3: ƒ moshouPc()
// length: 4
// __proto__: Array(0)
// qing: Array(4)
// 0: ƒ qingYeYe()
// 1: ƒ qingNaiNai()
// 2: ƒ qingBaBa()
// 3: ƒ qingMaMa()
// length: 4
// __proto__: Array(0)
// __proto__: Object
// __proto__: Object
// 先定义事件处理函数
// 请 类型 事件处理函数
function qingYeYe(){
console.log('我是请爷爷程序')
}
function qingNaiNai(){
console.log('我是请奶奶程序')
}
function qingBaBa(){
console.log('我是请爸爸程序')
}
function qingMaMa(){
console.log('我是请妈妈程序')
}
// 没收 类型 事件处理函数
function moshouPhone(){
console.log('我是没收手机程序')
}
function moshouHeadset(){
console.log('我是没收耳机程序')
}
function moshouIpad(){
console.log('我是没收Ipad程序')
}
function moshouPc(){
console.log('我是没收电脑程序')
}
// 写检查 类型 事件处理函数
function jianchaBan(){
console.log('我是交给班主任检查程序')
}
function jianchaJiao(){
console.log('我是交给教导主任检查程序')
}
function jianchaXiao(){
console.log('我是交给校长检查程序')
}
function jianchaJu(){
console.log('我是交给教育局长检查程序')
}
function abc(){
console.log('我是没有添加的程序')
}
Comments | NOTHING