我试图在每个循环的帮助下显示各种信息。 我为每个循环创建了一个循环,遍历项目列表。在此列表中还有另一个项目列表。
我的代码是:
@foreach (Invoice invoice in ViewBag.Invoices)
{
<table>
<tr>
<th>Customer</th>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
<th>Total Price</th>
</tr>
@foreach (OrderItem orderItem in invoice.OrderItems)
{
<tr>
<td>@invoice.Customer.Firstname @invoice.Customer.Lastname</td>
<td>@orderItem.Product.Title </td>
<td>@orderItem.Quantity </td>
<td>@orderItem.Product.Price </td>
<td>@orderItem.TotalPrice</td>
</tr>
}
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td class="border-top">@invoice.TotalPrice</td>
</tr>
</table>
}
但是,我不希望它两次显示客户名称。而且我不想让客户独立。因此,我尝试将起始标记与客户一起放在foreach循环之外,而是使用<tr>
标记结束foreach循环。所以它看起来像这样:
@foreach (Invoice invoice in ViewBag.Invoices)
{
<table>
<tr>
<th>Customer</th>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
<th>Total Price</th>
</tr>
<tr>
<td>@invoice.Customer.Firstname @invoice.Customer.Lastname</td>
@foreach (OrderItem orderItem in invoice.OrderItems)
{
<td>@orderItem.Product.Title </td>
<td>@orderItem.Quantity </td>
<td>@orderItem.Product.Price </td>
<td>@orderItem.TotalPrice</td>
</tr>
<tr>
}
<td></td>
<td></td>
<td></td>
<td></td>
<td class="border-top">@invoice.TotalPrice</td>
</tr>
</table>
}
更新的解决方案
我遵循@Ed Plunkett的明智词语并将本地字符串初始化为null。我创建了一个if / else语句来检查是否已经设置了上一个客户,并在循环结束时初始化了前一个客户的值。
@{string prevCust = null; }
@foreach (Invoice invoice in ViewBag.Invoices)
{
<table>
<tr>
<th>Customer</th>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
<th>Total Price</th>
</tr>
@foreach (OrderItem orderItem in invoice.OrderItems)
{
<tr>
@if (prevCust != invoice.Customer.Firstname + invoice.Customer.Lastname)
{
<td>@invoice.Customer.Firstname @invoice.Customer.Lastname</td>
}
else
{
<td></td>
}
<td>@orderItem.Product.Title </td>
<td>@orderItem.Quantity </td>
<td>@orderItem.Product.Price </td>
<td>@orderItem.TotalPrice</td>
</tr>
prevCust = invoice.Customer.Firstname + invoice.Customer.Lastname;
}
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td class="border-top">@invoice.TotalPrice</td>
</tr>
</table>
}
答案 0 :(得分:1)
我做的是穴居人风格:只需创建一个局部变量String prevCustomerName
,初始化为null,并在循环块结束时更新它。在循环块的开头,如果新客户名称与prevCustomerName
相同,请不要将其插入该行的HTML中。
我喜欢你在内循环中使用</tr>\n<tr>
的原始代码,但我花了一分钟才弄清楚你在做什么,而Razor似乎完全不知所措。而且你仍然需要通过一个特殊情况来丑陋,在非第一行上添加一个空单元格。如果您在任何一种情况下都坚持使用if
,请做穴居人。
答案 1 :(得分:0)
当在表中使用迭代时,它是有用的(即使对于您自己,不仅仅是剃须刀或您正在使用的任何视图引擎),使其尽可能保持结构化和简单。
(对你的问题的评论应该足够解释为什么这是一个好主意)
尝试使用每个发票的多个tr来实现您的目标。例如:
@foreach (Invoice invoice in ViewBag.Invoices)
{
<table>
<tr>
<th>Customer</th>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
<th>Total Price</th>
</tr>
<tr>
<td colspan="4">@invoice.Customer.Firstname @invoice.Customer.Lastname</td>
</tr>
@foreach (OrderItem orderItem in invoice.OrderItems)
{
<tr>
<td>@orderItem.Product.Title </td>
<td>@orderItem.Quantity </td>
<td>@orderItem.Product.Price </td>
<td>@orderItem.TotalPrice </td>
</tr>
}
<tr>
<td colspan="4"></td>
<td class="border-top">@invoice.TotalPrice</td>
</tr>
</table>
}
如果这有助于简化您的工作,您甚至可以为每张发票制作一张表。
答案 2 :(得分:0)
如果不是ASP专家,我想你必须以不同于其他人的方式处理第一行:
<tr>
<td>@invoice.Customer.Firstname @invoice.Customer.Lastname</td>
<td>@orderItem.Product.Title </td>
<td>@orderItem.Quantity </td>
<td>@orderItem.Product.Price </td>
<td>@orderItem.TotalPrice </td>
</tr>
现在处理循环中的其余部分,省略第一个(已处理的)元素:
@foreach (OrderItem orderItem in invoice.OrderItems.Skip(1))
{
<tr>
<td/>
<td>@orderItem.Product.Title </td>
<td>@orderItem.Quantity </td>
<td>@orderItem.Product.Price </td>
<td>@orderItem.TotalPrice </td>
</tr>
}
更通用的方法是使用带有索引的for
- 循环并检查您是否正在处理第一个元素:
@for(int i = 0; invoice.OrderItems.Count; i++)
{
<tr>
<td>@(i != 0 ? invoice.Customer.Firstname + " " + invoice.Customer.Lastname : "")</td>
<td>@invoice.OrderItems[i].Product.Title </td>
<td>@invoice.OrderItems[i].Quantity </td>
<td>@invoice.OrderItems[i].Product.Price </td>
<td>@invoice.OrderItems[i].TotalPrice </td>
</tr>
}
但是我不确定这是否是有效的ASP语法。