js实现观察者模式

52 阅读1分钟

观察者模式

主体调用方法来增删观察者,并且主动调用观察者的方法

实现主体观察者的绑定功能主要由主体实现,而重点功能实际上在观察者的方法中

先触发的是主体,然后主体通知观察者

观察者模式可以实现面包屑功能

class Subject{
    constructor() {
        this.observers=[]
    }
    add(observer){
        this.observers.push(observer)
    }
    remove(observer){
        this.observers = this.observers.filter(itme=>itme!==observer)
    }
    notify(){
        this.observers.forEach(item=>{
            item.update()
        })
    }
}

class Observer{
    constructor(name) {
        this.name=name
    }
    update(){
        console.log(this.name)
    }
}

const subject = new Subject()
const observer1 = new Observer('22')
const observer2 = new Observer('33')

subject.add(observer1)
subject.add(observer2)

subject.notify()
subject.remove(observer1)

setTimeout(()=>{
    subject.notify()
},1000)

实现面包屑

面包屑案例中,左边列表都是主体,而右边的面包屑是观察者 成功的将多对多的事件,通过函数传参,变成了一对多的事件,降低了耦合度 但是要注意add观察者,代码才能生效

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    .box{
        display: flex;
        height: 500px;
    }
    .box .left{
        width: 150px;
        background-color: aqua;
    }
    .box .right{
        flex: 1;
        background-color: azure;
    }
</style>
<body>
    <div class="box">
        <div class="left">
            <div class="label">label</div>
            <ul>
                <li>首页</li>
                <li>部门管理</li>
                <li>新闻管理</li>
                <li>站点管理</li>
            </ul>
        </div>
        <div class="right">
            <div class="bread"></div>
        </div>
    </div>
</body>
<script>
    class Subject{
        constructor() {
            this.observers=[]
        }
        notify(data){
            this.observers.forEach(item=>{
                item.changeText(data)
            })
        }
        add(observer){
            this.observers.push(observer)
        }
    }
    class Observe{
        constructor(name) {
            this.domObject=document.querySelector(name)
        }
        changeText(data){
            this.domObject.innerHTML=data
        }
    }
    const subject = new Subject()
    const observe1 = new Observe('.bread')
    const observe2 = new Observe('.label')

    subject.add(observe1)
    subject.add(observe2)

    const lis=document.querySelectorAll('li')
    lis.forEach(item=>{
        item.addEventListener('click',function (){
            subject.notify(this.innerHTML)
        })
    })
</script>
</html>