wepy IOS 数据渲染问题

fnx2tebb  于 2022-10-22  发布在  iOS
关注(0)|答案(1)|浏览(222)

提交ISSUE前请确保已认真阅读以下内容

  • Please read the following information carefully before you open an issue.*

在提交issue之前必须确认以下问题:

  • Please make sure you understand the following points:*

  • 必须是一个bug或者功能新增。

  • It must be a bug or a feature request

  • 必须是WePY相关问题,原生小程序问题去 开发者论坛

  • It must be a WePY issue.

  • 已经在issue中搜索过,并且没有找到相似的issue或者解决方案。

  • I searched issue already but I did't find any relevant issues or solutions.

  • 完善下面模板中的信息

  • Please filled out the following template

阅读完后请在提交的issue中删除以上内容,包括分割线

DELETE THE INFORMATION ABOVE(INCLUDE THE SEPARATION LINE) BEFORE YOU OPEN AN ISSUE

Description

[问题描述:站在其它人的Angular 尽可能清晰地、简洁地把问题描述清楚]
IOS上修改数据,调用$apply()更新,数据未渲染问题。

  1. 该问题主要存在在IOS上面,安卓和模拟器调试都没此问题
  2. 出现情况:
    2.1
    data格式定义如下:
data: {
 targetImages: [],
 choose: {
  list: []
 }
}

js方法如下:

// 初始化方法
  async init () {
    try {
      wepy.showLoading({
        title: '初始化图片'
      })
      const goods = await this.getGood()
      if (goods.code === 200) {
        this.array = goods.data.list || ''
      }
      let img = null
      for (let i = 0; i < this.imgs.length; i++) {
        img = {}
        const r = await this.getImage(this.imgs[i].image_url_url)
        img.url = this.imgs[i].image_url_url
        img.id = this.imgs[i].id
        let w = r.width
        let h = r.height
        let ch = (this.width / w) * h
        if (ch > this.height) { // 如果大于最大高度
          img.width = Math.floor((this.height / h) * w)
          img.height = this.height
        } else {
          img.width = this.width
          img.height = Math.floor(ch)
        }
        img.list = []
        const gl = this.imgs[i].goods_list
        if (gl && gl.length > 0) {
          gl.forEach(v => {
            if (v.image_info) {
              const xy = v.image_info.split('-')
              img.list.push({
                goods_id: v.goods_id,
                goods_title: v.goods_title,
                value: v.goods_title,
                x: xy[0],
                y: xy[1]
              })
            }
          })
        }
        this.targetImages.push(img)
      }
      this.imgIndex = 0
      this.choose = this.targetImages[this.imgIndex]
      wx.setNavigationBarTitle({
        title: `编辑(${this.imgIndex + 1}/${this.imgs.length})`
      })
      this.$apply()
    } catch (e) {
      console.error(e)
      wepy.showToast({
        title: '初始化图片失败',
        icon: 'none'
      })
    } finally {
      wepy.hideLoading()
    }
  }

// 选择一个产品,就给choose对象下面的list数组push一个对象
    bindPickerChange (e) {
      let index = e.currentTarget.dataset.index
      const name = this.array[index].goods_title
      this.addTag(name, this.array[index])
      this.show = false
      this.$apply()
    },
  addTag (name, data) {
    tid++
    const tag = {
      id: tid,
      x: 10,
      y: 10,
      value: name,
      data: data
    }
    this.choose.list.push(tag)
    this.$apply()
  }

发现类似情况在IOS上面比较多。
就是从一个数组中将一个对象赋值给data下面的对象,是引入方式的传递,所以数组中的对象和choose对象实际是同一个对象,当更改choose下面的对象,list下面的对象同时也同步更改,在调试器上基本上不会出问题。但是这种方式的实现逻辑在IOS上经常就是数据渲染不会更新视图,调用this.$apply()也是无效的。

[Description of the issue]

Environment

  • Platform: [开发者工具/iOS/Andriod/Web] IOS
  • Platform version: [对应工具或者iOS或者Andriod的版本号] 2.4.3
  • Wechat version: [微信版本号]
  • wepy-cli version: [wepy-cli -v] 1.7.3
  • wepy version: [在package.json里] 1.7.2
  • other version: [如果是插件问题,请列出问题插件的版本号]

Reproduce

[如何重现问题]
代码:

<template>
<view class="customers-container {{isPx ? 'xmjconfirm-container' : ''}}">
  <scroll-view scroll-y="true" class="scrollView">
    <view class="orderList">
      <view wx:for="{{detailData.order_item_list}}" wx:for-item="item" wx:key="item.id">
        <van-swipe-cell right-width="{{ 65 }}">
          <van-cell-group>
            <view class="wrapper">
              <view class="img-box">
                <image src="{{item.goods_cover_url}}" alt=""></image>
              </view>
              <view class="detail">
                <view class="title ellipsis-2">{{item.goods_title}}</view>
                <view class="label clearfix">
                  <text class="num">数量x{{item.number}}</text>
                  <text class="price">¥{{item.factory_amount}}</text>
                </view>
              </view>
            </view>
          </van-cell-group>
          <view class="djdj" slot="right" @tap="tzdj({{index}})">调整订金</view>
        </van-swipe-cell>
        <view class="box clearfix">
          <view class="wrapper-box">
            <view class="title">类型</view>
            <view class="detail" style="font-weight: 600">{{item.goods_cate}}</view>
          </view>
          <view class="wrapper-box center">
            <view class="title">定金</view>
            <view class="detail">¥{{item.deposit_amount}}</view>
          </view>
          <view class="wrapper-box">
            <view class="title">总价</view>
            <view class="detail price">{{item.factory_all_amount}}</view>
          </view>
        </view>
      </view>
    </view>
  </scroll-view>
  <view class="mjconfirm-btn">
    <view class="inline">
      <view class="label">
        <view class="label-item clearfix">
          订单总额
          <text class="price">¥{{totalAmount}}</text>
        </view>
        <view class="label-item sec-label clearfix">
          定金总额
          <text class="price price_border">¥{{totalDJ}}</text>
        </view>
        <view class="label-item last-label clearfix" @tap="xgjy">
          交付周期
          <text class="date">{{detailData.interaction_cycle}}天</text>
        </view>
      </view>
      <button @tap="comfie">确定</button>
    </view>
  </view>
  <van-popup show="{{ show }}" custom-style="Tjauto" z-index="9999" catch:close="onClose">
    <view class="tz-view">
      <view class="title">
        调价
        <image @tap="close" class="close" src="../../images/customer/close.png"></image>
      </view>
      <view class="wrapper">
        <view class="img-box">
          <image src="{{choose.goods_cover_url}}" alt=""></image>
        </view>
        <view class="detail">
          <view class="title ellipsis-2">{{choose.goods_title}}</view>
          <text class="price">¥{{choose.amount}}</text>
        </view>
        <text class="num">x{{choose.number}}</text>
      </view>
      <view class="input-view">
        <text class="tip">将订金调整为:</text>
        <view class="iv">
          <input type="number" value="{{choose.deposit_amount}}" bindinput="aBlur">
        </view>
        <text class="dw">元</text>
      </view>
      <button class="save" @tap="changeDJ">确认修改</button>
    </view>
  </van-popup>
  <van-popup show="{{ show2 }}" custom-style="Tjauto" z-index="9999" catch:close="onClose">
    <view class="tz-view">
      <view class="title">
        调整周期
        <image @tap="close2" class="close" src="../../images/customer/close.png"></image>
      </view>
      <view class="input-view">
        <text class="tip">将交付周期为:</text>
        <view class="iv">
          <input type="number" value="{{detailData.interaction_cycle}}" bindinput="zBlur">
        </view>
        <text class="dw">天</text>
      </view>
      <button class="save" @tap="saveZ">确认修改</button>
    </view>
  </van-popup>
</view>
</template>

<script>
import wepy from 'wepy'
import lf from 'lf'
import testMixin from '../../mixins/test'

export default class confirmOrder extends wepy.page {
config = {
  navigationBarTitleText: '确认订单',
  navigationBarTextStyle: '#fff',
  backgroundTextStyle: 'light',
  backgroundColor: '#2ebc88',
  navigationBarBackgroundColor: '#2ebc88',
  usingComponents: {
    'van-popup': '/components/vant/popup/index',
    'van-cell-group': '/components/vant/cell-group/index',
    'van-swipe-cell': '/components/vant/swipe-cell/index'
  }
}
mixins = [testMixin]
data = {
  show: false,
  show2: false,
  detailData: [],
  choose: {},
  detailId: '',
  sum: '',
  oldAmount: '',
  oldZQ: '',
  sum: 0
}

computed = {
  totalAmount () {
    const list = this.detailData.order_item_list || []
    let sum = 0
    list.forEach(v => {
      sum = sum + Number(v.amount)
    })
    return sum
  },
  totalDJ () {
    const list = this.detailData.order_item_list || []
    let sum = 0
    list.forEach(v => {
      sum = sum + Number(v.deposit_amount)
    })
    return sum
  }
}

methods = {
  close2 () {
    this.show2 = false
    this.detailData.interaction_cycle  = this.oldZQ
    this.$apply()
  },
  xgjy () {
    this.show2 = true
    this.oldZQ = this.detailData.interaction_cycle
    this.$apply()
  },
  zBlur (e) {
    this.detailData.interaction_cycle  = e.detail.value
    this.$apply()
  },
  async saveZ () {
    var reg = /^\+?[1-9][0-9]*$/
    if (!reg.test(this.detailData.interaction_cycle)) {
      this.detailData.interaction_cycle = this.oldZQ
      this.$apply()
      wepy.showToast({
        title: '请输入整数',
        icon: 'none'
      })
      return
    }
    try {
      const res = await lf.net.post('/Api/Factory/set_interaction_cycle', {
        order_id: this.detailData.id,
        interaction_cycle: this.detailData.interaction_cycle
      })
      if (res.code === 200) {
        this.show2 = false
        this.$apply()
        this.init()
        wepy.showToast({
          title: '操作成功',
          icon: 'none'
        })
      } else {
        wepy.showToast({
          title: res.info,
          icon: 'none'
        })
      }
    } catch (e) {
      console.error(e)
      wepy.showToast({
        title: '操作错误',
        icon: ''
      })
    }
  },
  toTel (number) {
    wepy.makePhoneCall({
      phoneNumber: String(number)
    })
  },
  tzdj (index) {
    this.show = true
    this.choose = this.detailData.order_item_list[index]
    this.oldAmount = this.choose.deposit_amount
    this.$apply()
  },
  close () {
    this.show = false
    this.choose.deposit_amount = this.oldAmount
    this.choose = {}
  },
  async changeDJ () {
    const reg = /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/;
    let value = this.choose.deposit_amount
    if (!reg.test(value)) {
      this.choose.deposit_amount = this.oldAmount
      this.$apply()
      wepy.showToast({
        title: '请输入正确金额',
        icon: 'none'
      })
      return
    }
    if (Number(value) > Number(this.choose.amount)) {
      this.choose.deposit_amount = this.oldAmount
      this.$apply()
      wepy.showToast({
        title: '不能大于总价',
        icon: 'none'
      })
      return
    }
    try {
      const res = await lf.net.post('/Api/Factory/order_item_update', {
        order_item_id: this.choose.id,
        deposit_amount: this.choose.deposit_amount
      })
      if (res.code === 200) {
        this.show = false
        this.choose = {}
        this.$apply()
       //  this.init() 发现IOS上有问题后,无奈就干脆调用一次初始化,才能渲染
        wepy.showToast({
          title: '操作成功',
          icon: 'none'
        })
      } else {
        wepy.showToast({
          title: res.info,
          icon: 'none'
        })
      }
    } catch (e) {
      console.error(e)
      wepy.showToast({
        title: '操作错误',
        icon: ''
      })
    }
  },
  aBlur (e) {
    const value = e.detail.value
    this.choose.deposit_amount = value
    this.$apply()
  },
  async comfie () {
    wepy.showLoading({
      title: '提交中...'
    })
    try {
      const res = await lf.net.post('/Api/Factory/order_check_commit', {
        id: this.detailData.id
      })
      wepy.hideLoading()
      if (res.code === 200) {
        this.show = false
        this.choose = {}
        this.$apply()
        wepy.showToast({
          title: '操作成功'
        })
        setTimeout(() => {
          wepy.navigateBack()
        }, 800)
      } else {
        wepy.showToast({
          title: res.info,
          icon: 'none'
        })
      }
    } catch (e) {
      console.error(e)
      wepy.hideLoading()
      wepy.showToast({
        title: '操作错误',
        icon: ''
      })
    }
  }
}
events = {}

async init () {
  this.getDetail()
}

async getDetail () {
  let result = await lf.net.post('/Api/Factory/order_detail', {
    order_id: this.detailId
  })
  if (result.code === 200) {
    this.detailData = result.data
    this.getSum(this.detailData.order_item_list)
    this.$apply()
  } else {
    wepy.showToast({
      title: result.info,
      icon: 'none'
    })
  }
}

getSum (list) {
  this.sum = 0
  for (let i = 0; i < list.length; i++) {
    this.sum += parseInt(list[i].number)
  }
}

onLoad (options) {
  this.detailId = options.id
  this.init()
}
}
</script>

[How to reproduce the issue]

Observed Results

[实际表现]
上面代码,choose的对象就是来源于detailData.order_item_list,在模拟器中表现都正常,但是在IOS上面修改之后就会不渲染,必须重新调用init初始化数据才会正常渲染。
[Observed Results]

Expected Results

[期望表现]

[Expected Results]

Relevant Code / Logs

// TODO(you): code or logs here to reproduce the problem
 // 可以使用小程序代码片段功能,方便其它人帮助你定位代码问题
 // 详情可参考这里:https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html
 ```
ztigrdn8

ztigrdn81#

刚自己测试了下,发现choose.list下面数据更改,IOS不渲染,但是我同时将这个choose.list的对象引用复制给data跟下面的定义一个新的对象,然后渲染的时候用新的对象去渲染就没任何问题。所以问题出在这个数组的渲染,必须在跟节点下面的才能在IOS下面渲染。
我上面所发的重现问题代码,估计是也同样的问题,因为数组是在detailData对象下面。所以导致数组中的对象修改无法渲染。

相关问题