编辑数据之后返回到列表页面怎么更新数据才好?
产品开发中总会遇见这样的需求,对于一个模型,我们有一个列表页面显示这些对象,点击跳转到详细页面,这个页面可以编辑这个对象,用户编辑并且保存之后返回上个页面,此时因为列表中某个对象已经被编辑了,列表页面如果不执行任何逻辑的话,页面仍然是旧数据,这时我们需要想办法更新这个列表页面。下面介绍两种办法:
订阅发布者模式进行通知
我们把列表页面称为 ListPage,详情页面称为 DetailPage。
虽然在大多数应用中,你可以通过一定的API获取到上一个页面的实例,如微信小程序中可以通过getCurrentPages()获取页面栈,然后通过直接调用页面的方法来进行一些操作,但是这个不具备通用性,如果你开发的是一个跨段的APP的话需要根据不同的平台来写不同的逻辑。所以在这里介绍的第一个方法我们通过订阅发布模式来进行,将此逻辑独立出去,不依赖平台。
具体做法是在进入ListPage时注册监听事件,并在回调中处理相应的逻辑,然后在其他任何需要更新数据时(如DetailPage中进行了编辑操作)发布事件,并携带自定义参数供ListPage使用
以uni-app应用为例,其他应用自己创建一个EventBus 即可
/** ListPage */
{
onLoad() {
this._itemChangeHandler = (changedItem) => {
// replace the item or refresh the item
}
uni.$on('<ModelName>:item-change', this._itemChangeHandler)
},
/** 记得在退出页面时取消监听 */
onUnload() {
uni.$off('<ModelName>:item-change', this._itemChangeHandler)
}
}
比如在DetailPage中点击了保存按钮之后,我们通知ListPage
/** DetailPage */
{
methods: {
save() {
doSave(/** some logic */)
.then(changedItem) {
uni.$emit('<ModelName>:item-change', changedItem)
}
}
}
}
好了,这样你就可以在保存数据之后更新ListPage了,甚至ListPage不需要再进行额外的 ajax 请求就可以更新到最新的视图。
在全局状态管理器中管理数据
不管是Vue栈还是React栈,生态中都有成熟的状态管理器用于管理状态。
以Vuex为例,如果页面中的数据引用自store中,那么当数据发生变化时,直接更新store中的数据就好了。
/** store/module/model.js */
const state = {
[<modelName>]: []
}
const mutations = {
setList() {
//
}
}
/** DetailPage */
{
methods: {
save() {
doSave(/** some logic */)
.then(changedItem) {
this.$store.commit('setList, {
modelName: <modelName>,
changedItem: changedItem
})
}
}
}
}
如果你的页面的数据一开始就不是设计在 store 中的,那么这种形式需要一定的改造成本,而且把页面数据存放在 store 中存在一定的争议,这时候就是见仁见智了,选择自己合适的方案就好。