MobX store 中的数据和页面逻辑层数据同步,以及页面逻辑层和视图层数据单向绑定的问题

(一)MobX store 中的数据和页面逻辑层数据没同步

(1)出错原因:觉得createStoreBindinds把store.carpoolOrder绑定给了this.carpoolOrder。用户触发openMap()后就可以更改store中的数据,同时更改了this.carpoolOrder。事实是前者实现了,后者没有。

(2)真相

虽然 MobX 通过反应式机制管理数据更新,但在某些情况下,看到 this.carpoolOrder 没有立即更新,原因包括:

  • 异步更新: MobX 的数据更新是异步的。在 openMapsuccess 回调中,当调用 this.setFieldthis.setStartPositionField 更新 store 的字段时,更新并不会立即反映到 this.carpoolOrder。因此,紧接着在同一个回调中访问 this.carpoolOrder 可能会得到旧值。

  • 批量更新: MobX 会批量处理状态更新,以优化性能。在某些情况下,多个更新操作可能会被一起处理,导致在某些时候访问 this.carpoolOrder 时,它并没有及时反映出最新的状态。

(3)验证

把store.carpoolOrder再给到this.carpoolOrder:

控制台打印可以看到carpoolOrder是有值了:

(二) 页面逻辑层和视图层数据不一致

(1)问题:那为什么页面数据和this.carpoolOrder不一致呢?

<view class="start-point-container" style="margin-top: 200px;">
  <view>你将从 
    <view class="select-point" bindtap="openMap"> {{carpoolOrder.startPoint || '选择起点'}} </view> 上车
  </view>
  <view class="selected-location">
    <view>选中的地点:</view>
    <view>名称:{{carpoolOrder1.startPoint || '未选择'}}</view>
    <view>地址:{{carpoolOrder1.startPosition.address || '未选择'}}</view>
    <view>经度:{{carpoolOrder1.startPosition.lng || '未选择'}}</view>
    <view>纬度:{{carpoolOrder1.startPosition.lat || '未选择'}}</view>
  </view>
</view>

(2)真相:data 是小程序的视图层与逻辑层之间的唯一桥梁。页面上的 wxml 只能访问 data 中的字段。虽然 createStoreBindings 会在 MobX store 中的数据变化时更新逻辑层中的字段(不是说刚刚,刚刚是手动更新的逻辑层this.carpoolOrder),但它不会自动更新 data,也就不会自动触发视图的重新渲染。因为微信小程序的视图层更新机制依赖于 this.setData。

(3)验证:用this.setData更新视图层的数据

可以看到数据已经全部渲染成功了: 

附示例代码: 

页面js

import { createStoreBindings } from 'mobx-miniprogram-bindings';
import { store } from '../../store/store';

Page({
  data: {
    carpoolOrder: {} 
  },
  onLoad() {
    // 使用 createStoreBindings 绑定 store 中的数据到页面
    this.storeBindings = createStoreBindings(this, {
      store,
      fields: ['carpoolOrder'],
      actions: ['setField','setStartPositionField']
    });
  },

  onUnload() {
    // 页面卸载时解除绑定
    this.storeBindings.destroyStoreBindings();
  },

  // 选择起点位置
  openMap() {
    wx.chooseLocation({
      success: (res) => {
        console.log('Location chosen:', res);
        // 更新 startPosition 的 startPoint,address, lng, lat  
        this.setField('startPoint', res.name);
        this.setStartPositionField('address', res.address);
        this.setStartPositionField('lng', res.longitude);
        this.setStartPositionField('lat', res.latitude);
        this.setData({
          carpoolOrder: store.carpoolOrder
        });         
      },
      fail: (err) => {
        console.error('Failed to choose location:', err);
      }
    });
  }
});

 页面wxml

<view class="start-point-container" style="margin-top: 200px;">
  <view>你将从 
    <view class="select-point" bindtap="openMap"> {{carpoolOrder.startPoint || '选择起点'}} </view> 上车
  </view>
  <view class="selected-location">
    <view>选中的地点:</view>
    <view>名称:{{carpoolOrder.startPoint || '未选择'}}</view>
    <view>地址:{{carpoolOrder.startPosition.address || '未选择'}}</view>
    <view>经度:{{carpoolOrder.startPosition.lng || '未选择'}}</view>
    <view>纬度:{{carpoolOrder.startPosition.lat || '未选择'}}</view>
  </view>
</view>

store.js

// store.js
import { observable } from 'mobx-miniprogram';

export const store = observable({
  carpoolOrder: {
    members: [],
    startPoint: null,
    startPosition:{
      address:'',
      lng:'',
      lat:'',       
    },
    endPoint: null,
    endPosition:{
      address:'',
      lng:'',
      lat:'',       
    },
    status: '',
    time: ''
},

  // 更新拼车订单的整个数据对象
  setCarpoolOrder(newOrder) {
    this.carpoolOrder = newOrder;
    this.saveCarpoolOrder(); // 持久化
  },

  // 更新拼车订单中指定字段的数据
  setField(key, value) {
    this.carpoolOrder[key] = value;
    this.saveCarpoolOrder(); // 持久化
  },

  // 更新 startPosition 中的单个字段
  setStartPositionField(field, value) {
    this.carpoolOrder.startPosition[field] = value;
    this.saveCarpoolOrder(); // 持久化
  },

  // 保存拼车订单到本地存储
  saveCarpoolOrder() {
    wx.setStorageSync('carpoolOrder', this.carpoolOrder);
  },

  // 从本地存储加载拼车订单
  loadCarpoolOrder() {
    const savedOrder = wx.getStorageSync('carpoolOrder');
    if (savedOrder) {
      this.carpoolOrder = savedOrder;
    }
  }
});

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值