C#对于表中的每个循环?

时间:2016-10-05 13:28:47

标签: c# asp.net-mvc foreach

我试图在每个循环的帮助下显示各种信息。 我为每个循环创建了一个循环,遍历项目列表。在此列表中还有另一个项目列表。

至于现在,它显示如下: enter image description here

我的代码是:

@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>
}

3 个答案:

答案 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语法。