Vue.js - 即使对象存在也无法读取属性

Kad*_*y03 1 modal-dialog firebase firebase-realtime-database vuejs2

我使用vue-resourcefirebase获取数据。基本上,当我遍历orders目录下的每个对象时,我匹配该对象的userId,在users目录下找到该对象,并将其作为嵌套对象(userData)与检索到的orders对象一起保存在我的本地数组中。这是我的代码:

//retrieve objects from orders
this.$http.get('https://nots-76611.firebaseio.com/Orders.json').then(function(data){
        return data.json();
    }).then(function(data){
        var ordersArray = [];
        for (let key in data){
            data[key].id = key;
            data[key].measurementsArray = Object.entries(data[key].measurements).sort();
            //retrieve a specific user based on the userId of each orders object
            this.$http.get('https://nots-76611.firebaseio.com/Users/' + data[key].userId + '.json').then(function(userdata){
              return userdata.json();
            }).then(function(userdata){
              data[key].userData = userdata; //store the object
            });
            ordersArray.push(data[key]); //pass the object along the userData
        }
        this.orders = ordersArray;
        console.log(this.orders);
    });
Run Code Online (Sandbox Code Playgroud)

控制台中显示的对象结构非常好:

在此处输入图片说明

但是当我尝试时,通过以下方式访问 dom 中的嵌套对象{{ order.userData.Address }}

<tr v-for="order in orders"
<dialog class="mdl-dialog" ref="userDialog">
                  <h4 class="mdl-dialog__title">Customer's Information</h4>
                  <div class="mdl-dialog__content">
                    {{ order.userData.Address }}
                  </div>
                  <div class="mdl-dialog__actions">
                    <button class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored mdl-js-ripple-effect" v-on:click="closeUser(ndx)">
                      OK
                    </button>
                  </div>
                </dialog>
</tr>
Run Code Online (Sandbox Code Playgroud)

它说Error in render function: "TypeError: Cannot read property 'Address' of undefined"。我不明白,因为我可以轻松检索测量对象(也是嵌套对象)中的属性

我在检索过程中搞砸了吗?还是在 DOM 渲染中?

编辑:我尝试使用{{ order }}而不是,{{ order.userData.Address }}似乎userData对象没有存储在每个orders对象中

另外,我注意到userData对象的显示方式与measurements最初与父对象一起存储在那里的对象的显示方式有些奇怪:

在此处输入图片说明

Ber*_*ert 6

这里有两个主要问题。

首先,数据是异步检索的,这意味着当组件第一次呈现时它不存在。在您使用的模板中

order.userData.Address
Run Code Online (Sandbox Code Playgroud)

有一个时间点有orders但没有userData,因为数据还没有被检索到。在这种情况下,Vue 尝试渲染订单,并尝试渲染order.userData.Address,但没有userData. 这就是为什么您会收到错误“无法读取未定义的属性‘地址’”的原因。为了解决这个问题,你应该使用一个守卫来确保只Address在它可用时才尝试渲染。

{{orders.userData && orders.userData.Address}}
Run Code Online (Sandbox Code Playgroud)

这将防止错误。

有一个您可能还没有注意到的次要错误。userData不是反应性的。这样做的原因是因为Vue 无法检测将对象添加到数据何时将属性添加到对象。代码设置userData如下:

data[key].userData = userdata;
Run Code Online (Sandbox Code Playgroud)

这发生在将orders数组添加到 Vue 之后,因为它是在异步调用中执行的。相反,你应该使用,

this.$set(data[key], 'userData', userdata)
Run Code Online (Sandbox Code Playgroud)

  • @GTHell 我能理解你的困惑。有两个概念在起作用。首先,在 javascript 中,如果第一个值为 true,则 &amp;&amp; 表达式的计算结果为表达式的右侧。其次,布尔表达式 **short circuit** 这意味着,如果表达式的第一部分不为真,则第二部分甚至不会被评估(因为表达式显然是假的)。这允许编写一个简短的 `if` 语句,这在模板之类的东西中很有用。您可以直接在控制台中尝试。尝试在控制台中输入 1 &amp;&amp; 2,结果为 2。 (2认同)