Sui Move前端共学笔记(五)-订阅发布者模式

121 阅读2分钟

HOH水分子社区,是一个专注于编程、教育和创新的社区。

需求

同笔记(四),使用订阅发布者模式完成需求。

订阅发布者模式

订阅发布者模式,同字面意思,用户可以在消息推送中心订阅,当发布者在平台发布信息时,平台会将该信息推送给订阅者。在react中,也可通过这种模式实现跨组件通信。

消息推送平台

var messagesPlatform = {
// 消息推送中心定义
    list:[],
    // 空白列表,用于存储订阅者信息。
    subscribe(callback) {
    // 订阅函数,调用该函数订阅推送,成为订阅者。
        this.list.push(callback);
        // 存储订阅者信息。
    },

    publish(message){
    // 消息推送函数,message为推送内容
        this.list.forEach(callback => {
            // console.log(111);
            callback && callback(message)
            // 判断是否存在回调函数,如果存在则调用函数传递推送内容message。
        })
    }
}

订阅者调用订阅函数

messagesPlatform.subscribe((message)=>{
    console.log("111",message);
})

messagesPlatform.subscribe((message)=>{
    console.log("222",message);
})
// 调用者调用订阅函数,传递一个回调函数给消息推送中心。

发布者调用Push发送消息

messagesPlatform.publish("推送消息");

订阅者调用subscribe方法传入一个回调函数给消息推送平台,消息推送平台将该回调函数存储在List中,当发布者调用push时,消息推送平台遍历list中的回调函数将信息传递给订阅者。

效果展示:

image.png

需求应用

当点击电影列表中的电影时,电影概述中显示该电影概述信息,所以在这个需求中电影列表中的电影作为发布者,概述信息展示作为订阅者。

消息订阅平台

var messagesPlatform = {
    list:[],
    subscribe(callback) {
        this.list.push(callback);
    },

    publish(filmDetail){
        this.list.forEach(callback => {
            // console.log(111);
            callback && callback(filmDetail)
        })
    }
}

这个代码我们上面解释过了。

首页 APP

class APP extends Component {
    constructor() {
        super();
        this.state={
            filmList:[],
        }
        axios.get("/test.json").then(
            res => {
                this.setState({filmList:res.data.data.films});
            }
        )
    }
    // 初始化App类组件
    
    render() {
        return (
            <div>
                {this.state.filmList.map(item=>
                    <FilmList key={item.filmId} {...item}></FilmList>
                )}
                // 与之前不同,这里不再传入回调函数给FilmList
                <FilmDetail />
                // 与之前不同,这里也不再传入属性给FilmDetail
            </div>
        );
    }
}

在这里,首页不再充当中间人了。

电影概述组件 FilmDetail

class FilmDetail extends Component{
    constructor() {
        super();
        this.state={
            filmDetail:""
        }
        messagesPlatform.subscribe((message)=>{
            this.setState({filmDetail:message});
        })
    }
    // 与之前不同,概述组件中新增了类初始化,当该组件被创建时,调用messagePlatform.surscribe函数订阅消息推送平台传递一个回调函数,当接受到消息推送内容时将内容存储到状态filmDetail中。
    render() {
        return (
            <div className={"filmDetail"}>
                {this.state.filmDetail}
                // 在这里显示状态filmDetail值。
            </div>
        )
    }
}

电影列表组件 filmList

class FilmList extends Component{
    render() {
        let {name,poster,grade,synopsis }=this.props
        return (
            <div className={"filmItem"} onClick={()=>{
                messagesPlatform.publish(synopsis);
                // 之前调用onEvent将sysnopsis传给父组件,现在调用消息推送函数直接将内容推送至订阅者FilmDetail。
            }}>
                <img src={poster} alt={name}/>
                <h4>{name}</h4>
                <div>观众评分:{grade}</div>
            </div>
        )
    }
}

效果展示:

首页:

image.png

点击电影显示概述信息

image.png

Contact US

HOH水分子公众号 Alya @HOH Jane @HOH