|
|
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中的回调函数将信息传递给订阅者。
效果展示:
需求应用
当点击电影列表中的电影时,电影概述中显示该电影概述信息,所以在这个需求中电影列表中的电影作为发布者,概述信息展示作为订阅者。
消息订阅平台
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>
)
}
}
效果展示:
首页:
点击电影显示概述信息
Contact US
|
|
|
|