嵌套的 v-for 循环不渲染
nested v-for loop not rendering
我正在尝试以类似行的方式显示 table 满订单和相应的订单详细信息。但是,我 运行 陷入了一个难题。那里有天才吗?我已经尝试了各种变体来解决这个问题,但我被卡住了。有人提到也许使用 'computed' 属性 可以解决问题,但我无法让它工作 >=/。一点帮助,也许很多帮助,将不胜感激!
<div id="MyOrdersApp" class="table-responsive">
<table class="table table-striped table-bordered table-condensed">
<thead>
<tr style="color:black;font-size:2em;">
<th style="text-align:center;">Order Id</th>
<th style="text-align:center;">ProductIdsAndQuantity</th>
<th style="text-align:center;">Total Cost</th>
<th style="text-align:center;">Order Status</th>
<th style="text-align:center;">Shipment Tracking URL</th>
<th style="text-align:center;">Created Date</th>
</tr>
</thead>
<tbody>
<tr v-for="(order, i) in parsedOrders" style="background-color:snow;text-align:center;" class="align-content-center;">
<td>{{order.OrderId}}</td>
<td>
<ul>
<li v-if="order.CartLineItems != null" v-for="item in order.CartLineItems;" :key="uniqueKey">
<img :src="item.ProductImageUrl" />
<span>{{item.ProductName}} | </span>
<span>Quantity: {{item.Quantity}} | </span>
</li>
</ul>
</td>
<td style="color:black;font-size:1.5em;font-weight:bold;">{{order.TotalRevenue | currency }}</td>
<td>{{order.OrderStatus}}</td>
<td>{{order.ShipmentTrackingURL}}</td>
<td>{{order.CreatedDate | formatDate }}</td>
</tr>
</tbody>
</table>
</div>
<script>
var MyOrdersApp = new Vue({
el: '#MyOrdersApp',
data: {
parsedOrders: [],
theOrders: [],
uniqueKey: 0
},
computed: {
cartLineItems: function () {
return this.parsedOrders[0].CartLineItems;
}
},
methods: {
getMyOrders: function () {
var scope = this;
this.$http.get("https://" + location.host + "/Home/GetMyOrders").then(resp => {
if (resp.status == 200) {
this.theOrders = resp.body;
scope.setCartLineItems();
}
});
},
setCartLineItems: function () {
var scope = this;
var cartLineItems = [];
var cartDict = {};
for (var i = 0; i < this.theOrders.length; i++) {
cartDict = {};
cartLineItems = [];
cartDict = JSON.parse(this.theOrders[i].ProductIdsAndQuantity).CartLineItems;
for (var key in cartDict) {
var lineItem = JSON.parse(cartDict[key]);
cartLineItems.push(lineItem);
}
//this.allorders[i].CartLineItems = cartLineItems;
//scope.$set(this.allorders[i], 'CartLineItems', cartLineItems);
//this.theOrders[i].CartLineItems = cartLineItems;
scope.$set(this.theOrders[i], 'CartLineItems', cartLineItems);
}
this.parsedOrders = this.theOrders;
console.log("~~ Parsed Cart! ~~ ");
console.log(this.parsedOrders);
console.log(this.parsedOrders[1].CartLineItems);
}
},
mounted: function () {
var scope = this;
this.getMyOrders();
setTimeout(x => { scope.$forceUpdate(); scope.uniqueKey++; }, 1000);
}
});
</script>
我应该如何修改它才能正确显示 'CartLineItems' 中的值??
顺便说一句,解析后的订单看起来像这样:
如果我注释掉内部的 v-for,其他列显示得很好并且 table 看起来像这样:
更多背景...当我通过 $http 调用和服务器 returns JSON 的数组获取订单时,ProductIdsAndQuantity 属性 需要解析为一个 JSON 对象,然后在相关订单上设置为它自己的 属性。这里棘手的部分是 Vue 组件似乎没有对订单对象数组数据的变化做出反应。因此,需要对 parsedOrders 属性 and/or 使用 scope.$forceUpdate();或 scope.uniqueKey++;。这些是针对 Vue 组件不重新渲染的问题提出的解决方案。但是,这些解决方案不起作用。所以我一直在摸不着头脑...
您不能在导致问题的同一语句中同时使用 v-for 和 v-if。所以在这种情况下尝试使用 computed
<tbody>
<tr v-for="(order, i) in parsedOrders" style="background-color:snow;text-align:center;" class="align-content-center;">
<td>{{order.OrderId}}</td>
<td>
<ul>
<li v-for="(item, index) in getCartLineItems(order)" :key="index">
<img :src="item.ProductImageUrl" />
<span>{{item.ProductName}} | </span>
<span>Quantity: {{item.Quantity}} | </span>
</li>
</ul>
</td>
<td style="color:black;font-size:1.5em;font-weight:bold;">{{order.TotalRevenue | currency }}</td>
<td>{{order.OrderStatus}}</td>
<td>{{order.ShipmentTrackingURL}}</td>
<td>{{order.CreatedDate | formatDate }}</td>
</tr>
</tbody>
并在计算中
computed: {
getCartLineItems() {
return order => {
if(order?.CartLineItems && order.CartLineItems.length) return order.CartLineItems;
return [];
}
}
}
我正在尝试以类似行的方式显示 table 满订单和相应的订单详细信息。但是,我 运行 陷入了一个难题。那里有天才吗?我已经尝试了各种变体来解决这个问题,但我被卡住了。有人提到也许使用 'computed' 属性 可以解决问题,但我无法让它工作 >=/。一点帮助,也许很多帮助,将不胜感激!
<div id="MyOrdersApp" class="table-responsive">
<table class="table table-striped table-bordered table-condensed">
<thead>
<tr style="color:black;font-size:2em;">
<th style="text-align:center;">Order Id</th>
<th style="text-align:center;">ProductIdsAndQuantity</th>
<th style="text-align:center;">Total Cost</th>
<th style="text-align:center;">Order Status</th>
<th style="text-align:center;">Shipment Tracking URL</th>
<th style="text-align:center;">Created Date</th>
</tr>
</thead>
<tbody>
<tr v-for="(order, i) in parsedOrders" style="background-color:snow;text-align:center;" class="align-content-center;">
<td>{{order.OrderId}}</td>
<td>
<ul>
<li v-if="order.CartLineItems != null" v-for="item in order.CartLineItems;" :key="uniqueKey">
<img :src="item.ProductImageUrl" />
<span>{{item.ProductName}} | </span>
<span>Quantity: {{item.Quantity}} | </span>
</li>
</ul>
</td>
<td style="color:black;font-size:1.5em;font-weight:bold;">{{order.TotalRevenue | currency }}</td>
<td>{{order.OrderStatus}}</td>
<td>{{order.ShipmentTrackingURL}}</td>
<td>{{order.CreatedDate | formatDate }}</td>
</tr>
</tbody>
</table>
</div>
<script>
var MyOrdersApp = new Vue({
el: '#MyOrdersApp',
data: {
parsedOrders: [],
theOrders: [],
uniqueKey: 0
},
computed: {
cartLineItems: function () {
return this.parsedOrders[0].CartLineItems;
}
},
methods: {
getMyOrders: function () {
var scope = this;
this.$http.get("https://" + location.host + "/Home/GetMyOrders").then(resp => {
if (resp.status == 200) {
this.theOrders = resp.body;
scope.setCartLineItems();
}
});
},
setCartLineItems: function () {
var scope = this;
var cartLineItems = [];
var cartDict = {};
for (var i = 0; i < this.theOrders.length; i++) {
cartDict = {};
cartLineItems = [];
cartDict = JSON.parse(this.theOrders[i].ProductIdsAndQuantity).CartLineItems;
for (var key in cartDict) {
var lineItem = JSON.parse(cartDict[key]);
cartLineItems.push(lineItem);
}
//this.allorders[i].CartLineItems = cartLineItems;
//scope.$set(this.allorders[i], 'CartLineItems', cartLineItems);
//this.theOrders[i].CartLineItems = cartLineItems;
scope.$set(this.theOrders[i], 'CartLineItems', cartLineItems);
}
this.parsedOrders = this.theOrders;
console.log("~~ Parsed Cart! ~~ ");
console.log(this.parsedOrders);
console.log(this.parsedOrders[1].CartLineItems);
}
},
mounted: function () {
var scope = this;
this.getMyOrders();
setTimeout(x => { scope.$forceUpdate(); scope.uniqueKey++; }, 1000);
}
});
</script>
我应该如何修改它才能正确显示 'CartLineItems' 中的值??
顺便说一句,解析后的订单看起来像这样:
如果我注释掉内部的 v-for,其他列显示得很好并且 table 看起来像这样:
更多背景...当我通过 $http 调用和服务器 returns JSON 的数组获取订单时,ProductIdsAndQuantity 属性 需要解析为一个 JSON 对象,然后在相关订单上设置为它自己的 属性。这里棘手的部分是 Vue 组件似乎没有对订单对象数组数据的变化做出反应。因此,需要对 parsedOrders 属性 and/or 使用 scope.$forceUpdate();或 scope.uniqueKey++;。这些是针对 Vue 组件不重新渲染的问题提出的解决方案。但是,这些解决方案不起作用。所以我一直在摸不着头脑...
您不能在导致问题的同一语句中同时使用 v-for 和 v-if。所以在这种情况下尝试使用 computed
<tbody>
<tr v-for="(order, i) in parsedOrders" style="background-color:snow;text-align:center;" class="align-content-center;">
<td>{{order.OrderId}}</td>
<td>
<ul>
<li v-for="(item, index) in getCartLineItems(order)" :key="index">
<img :src="item.ProductImageUrl" />
<span>{{item.ProductName}} | </span>
<span>Quantity: {{item.Quantity}} | </span>
</li>
</ul>
</td>
<td style="color:black;font-size:1.5em;font-weight:bold;">{{order.TotalRevenue | currency }}</td>
<td>{{order.OrderStatus}}</td>
<td>{{order.ShipmentTrackingURL}}</td>
<td>{{order.CreatedDate | formatDate }}</td>
</tr>
</tbody>
并在计算中
computed: {
getCartLineItems() {
return order => {
if(order?.CartLineItems && order.CartLineItems.length) return order.CartLineItems;
return [];
}
}
}