Open LYlanfeng opened 5 years ago
提交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
[问题描述:站在其它人的角度尽可能清晰地、简洁地把问题描述清楚] IOS上修改数据,调用$apply()更新,数据未渲染问题。
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 [如何重现问题] 代码: ```javascript <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]
[实际表现] 上面代码,choose的对象就是来源于detailData.order_item_list,在模拟器中表现都正常,但是在IOS上面修改之后就会不渲染,必须重新调用init初始化数据才会正常渲染。 [Observed Results]
[期望表现]
[Expected Results]
// TODO(you): code or logs here to reproduce the problem // 可以使用小程序代码片段功能,方便其它人帮助你定位代码问题 // 详情可参考这里:https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html ```
刚自己测试了下,发现choose.list下面数据更改,IOS不渲染,但是我同时将这个choose.list的对象引用复制给data跟下面的定义一个新的对象,然后渲染的时候用新的对象去渲染就没任何问题。所以问题出在这个数组的渲染,必须在跟节点下面的才能在IOS下面渲染。 我上面所发的重现问题代码,估计是也同样的问题,因为数组是在detailData对象下面。所以导致数组中的对象修改无法渲染。
提交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
[问题描述:站在其它人的角度尽可能清晰地、简洁地把问题描述清楚] IOS上修改数据,调用$apply()更新,数据未渲染问题。
js方法如下:
// 选择一个产品,就给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() }
[How to reproduce the issue]
Observed Results
[实际表现] 上面代码,choose的对象就是来源于detailData.order_item_list,在模拟器中表现都正常,但是在IOS上面修改之后就会不渲染,必须重新调用init初始化数据才会正常渲染。 [Observed Results]
Expected Results
[期望表现]
[Expected Results]
Relevant Code / Logs