jameslai
jameslai
  • 发布:2021-10-07 23:04
  • 更新:2023-04-17 16:40
  • 阅读:2112

uniapp 动态数据无法绑定

分类:uni-app

如下代码片段:

  1. 从另外一个页面跳转到本页面的时候携带一个字典的list,在本页面onload的时候赋值(push)给本页面定义的checkitems;
  2. 给checkitems里面的每个元素增加了一个属性“ci_f_extend",然后将此属性用v-if绑定至view。
  3. 用v-bind绑定了checkitems列表里面的每一项的元素ci_status。
    现在发现步骤2 v-if的绑定没有效果,但是步骤3的v-bind是有效的。也就是步骤2在js里面将其值在一些按钮的onclick里面进行了改变,但是view里面并没有体现出任何改变。

之前checkitems在本地初始化了一些测试的固定的值的时候,这些绑定都是没问题的。自动改成了从另外一个页面传了list过来,然后push到本地的list之后,所有的绑定都没有效果了。不知道这种问题如何解决? 或者正确的实现方法是什么?
谢谢老司机先!

<template>  
    <view class="cover-view">  
        <view class="uni-padding-wrap-cust">  

            <view class="ci_stype" v-for="(checkitem, ciidx) in checkitems" :key="ciidx">  
                <view :class="checkitem.ci_status_style">  
                    <view class="vciname_style">{{checkitem.ci_item_name}}</view>  
                    <view class="yesno_view_style uni-flex uni-row">  
                        <button class="cu-btn  " v-bind:class="[checkitem.ci_status == 1 ? 'lines-green': 'line-gray']" @click="click_yesno(ciidx, 1)"><text class="cuIcon-check"></text></button>  

                    </view>  
                </view>  
                <view v-if="checkitem.ci_f_extend" class = "ci_expend_style">  
                    <view class="inputview_style">  
                        <input class="uni-input-cust" maxlength="20" :value="checkitem.ci_checker_comment" placeholder="请输入" />  
                    </view>  

                </view>  
            </view>  
        </view>  

        <view class="uni-padding-wrap-cust">  
            <view class="padding flex flex-direction">  
                <button class="cu-btn margin-tb-sm lg bg-dark-blue-cust" @tap="submit_checksheet">提交</button>  
            </view>  

        </view>  
    </view>  
</template>  
<script>  

import {  
    mapState,  
    mapMutations  
} from 'vuex';  

export default {  
    computed: mapState([ 'hasLogin','uerInfo']),  

    data() {  
        return {  
            cs_detail:{},  
            checkitems:[],  

        }  
    },  
    onLoad(event) {  
        this.checkLogin('../checksheet', '2');  
        var para;  
        const payload = event.para || event.payload;  
        try {  
            para = JSON.parse(decodeURIComponent(payload));  
        } catch (error) {  
            para = JSON.parse(payload);  
        }  

        let url = this.$serverUrl;  
        console.log("url="+url);  
        uni.request({  
            url: url,  
            header: this.global_getHttpHeader(),  
            data: {},  
            method: "GET",  
            success: e => {  
                if (e.statusCode == 200) {  
                    console.log("e is:"+JSON.stringify(e));  

                    if(e.data.code === 'OK'){  

                        for(var i=0; i< this.cs_detail.cs_items.length; i++ ){  

                            this.checkitems.push(this.cs_detail.cs_items[i]);  
                        }  

                        console.log("checksheet start modify:");  
                        for(var i=0; i<this.checkitems.length; i++){  
                            this.checkitems[i].ci_f_extend = false;  
                            this.checkitems[i].ci_status_style = 'ci_basic_stype_unset';  
                        }  

                    }  
                    else if(e.data.code === "NotFound"){  
                        console.log("can not found the checksheet")  
                    }  
                    else{  
                        console.log("get latest checksheet: internal error")  
                    }  
                }  
            },  
        });  

    },  

    methods: {  
        click_expend(ciidx){  
            this.checkitems[ciidx].ci_f_extend = !this.checkitems[ciidx].ci_f_extend;  
            console.log("["+ciidx+"]expend clicked, new value is:"+this.checkitems[ciidx].ci_f_extend);  
        },  

        submit_checksheet(){  
            let that = this;  
            var navData = JSON.stringify(this.$data);  

            console.log("in source page, data is:"+navData);  
            uni.navigateTo({  
                url: 'checkresult?para=' + encodeURIComponent(JSON.stringify(navData)),  
            });   
        }  
    }  
}  
</script>  

<style>  

</style>
2021-10-07 23:04 负责人:无 分享
已邀请:
3***@qq.com

3***@qq.com

你的 ci_f_extend 和 ci_status_style 字段不是响应式字段,应先给这两个字段赋值,再往 checkitems 里 push,或者使用 $set 进行响应式绑定。

jameslai

jameslai (作者)

多谢回复:)
我改了改代码,尝试了这两种方式,似乎都不行,最后还是需要forceupdate才能触发更新view。

方法一: 在push之前先赋值。改了之后问题依旧存在。

onload(){  
...  
                        for(var i=0; i< this.cs_detail.cs_items.length; i++ ){  
                            this.cs_detail.cs_items[i].ci_f_extend = false;  
                            this.cs_detail.cs_items[i].ci_status_style = 'ci_basic_stype_unset';  
                            this.checkitems.push(this.cs_detail.cs_items[i]);  
                            console.log("["+i+"]  "+JSON.stringify(this.checkitems[i]));  
                        }  
}

方法二: 使用$set

        click_expend(ciidx){  
            //this.checkitems[ciidx].ci_f_extend = !this.checkitems[ciidx].ci_f_extend;  
            //this.$forceUpdate();  
            this.$set(this.checkitems[ciidx], "ci_f_extend", !this.checkitems[ciidx].ci_f_extend);  
            console.log("expend clicked, new value is:"+ this.checkitems[ciidx].ci_f_extend);  
        },

使用this.$forceUpdate()是可以,但是觉得似乎不合适。毕竟是响应式系统,不应该手动去触发update。

其实我感觉最根本的问题是:这个页面的数据是从上一个页面传递过来的动态数据,数据比较复杂。比如

data=[  
{key:value, key2, value2, key3:[value31, value32, value33], key4:value4},  
{key:value},  
{},  
...  
]

这个数据是数组嵌套字典,然后又嵌套数组。本来我理解,直接在data里面将传过来的数据在onload保存(直接一个赋值语句),之后直接用传递过来的这个动态的数据去渲染页面,并做动作绑定。但是遇到了很多的问题。
uniapp在做数据绑定的时候,是依赖于data里面预先定义好的固定数据? 对于这种动态数据处理不行? 还是我用错了方法?

jameslai

jameslai (作者)

如果uniapp/vue做动态数据绑定依赖的data是在onload执行完成(onload会设置data)之后的data,那从上一个页面获取的参数数据应该可以被绑定。看起来好像的确也是这样的?

l***@163.com

l***@163.com

可以试下不直接object.属性赋值,试一下用个对象接收,然后为这个对象修改属性,例如:
this.http.getCustomerCollocation(data).then((res) => {
let dataSource = res.result.data
for(let i =0;i<dataSource.length;i++){
let item = dataSource[i];
item.isEdit = false;
this.tableData.push(item);
}
this.total = res.result.totalCount
this.loading = false
})
虽然有点蠢但应该是有效的

要回复问题请先登录注册