刷新上个(前一页)页面的两种方式

448 阅读2分钟

编辑数据之后返回到列表页面怎么更新数据才好?

产品开发中总会遇见这样的需求,对于一个模型,我们有一个列表页面显示这些对象,点击跳转到详细页面,这个页面可以编辑这个对象,用户编辑并且保存之后返回上个页面,此时因为列表中某个对象已经被编辑了,列表页面如果不执行任何逻辑的话,页面仍然是旧数据,这时我们需要想办法更新这个列表页面。下面介绍两种办法:

订阅发布者模式进行通知

我们把列表页面称为 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 中存在一定的争议,这时候就是见仁见智了,选择自己合适的方案就好。