【问题标题】:Getting index value on razor foreach在剃刀foreach上获取索引值
【发布时间】:2012-05-06 18:31:18
【问题描述】:

在我的视图中,我在一个剃刀 foreach 循环中迭代 List<T>,它呈现了一个部分。在部分中,我正在渲染一条记录,我希望在我的视图中连续显示 4 条记录。我有一个用于两端列的 css 类,因此需要在部分中确定调用是第一条记录还是第四条记录。在我的部分中识别这一点以输出正确代码的最佳方法是什么?

这是我的主页,其中包含循环:

@foreach (var myItem in Model.Members){

        //if i = 1
        <div class="grid_20">
        <!-- Start Row -->

        //is there someway to get in for i = 1 to 4 and pass to partial?
        @Html.Partial("nameOfPartial", Model)

        //if i = 4 then output below and reset i to 1
        <div class="clear"></div>
        <!-- End Row -->
        </div>

}

我想我可以创建一个 int ,我可以在每次传递时更新它并在这里渲染文本没有问题,但它将整数值传递到我更关心的部分。除非有更好的方法。

这是我的部分:

@{
switch()
case 1:
        <text>
        <div class="grid_4 alpha">
        </text>
break;
case 4:
        <text>
        <div class="grid_4 omega">
        </text>
break;
default:
        <text>
        <div class="grid_4">
        </text>
break;
}

        <img src="Content/960-grid/spacer.gif" style="width:130px; height:160px; background-color:#fff; border:10px solid #d3d3d3;" />
        <p><a href="member-card.html">@Model.Name</a><br/>
        @Model.Job<br/>
        @Model.Location</p>
</div>

不确定我今天是否有一个金发碧眼的日子,这非常容易,但我想不出传递 int 值的最佳方法。希望有人能提供帮助。

【问题讨论】:

标签: asp.net-mvc asp.net-mvc-2 razor partial-views


【解决方案1】:

看看this solution using Linq. 他的例子很相似,他需要为每第三个项目使用不同的标记。

foreach( var myItem in Model.Members.Select(x,i) => new {Member = x, Index = i){
    ...
}

【讨论】:

  • 但是如果我将我的成员传递给部分,我将如何在其中获取索引?我假设我必须创建一个单独的 ViewModel 来封装我的成员传递到我的部分。感觉很恶心。只是想知道是否有更好的方法?
  • 好的。是的,这是一种方法,或者您可以使用匿名对象作为模型并将动态指定为模型类型。有没有办法将切换逻辑移动到父模板中,这样就不需要传入索引值了?如果你这样做了,你原来的可能不太优雅的解决方案仍然有效。
【解决方案2】:

您是否有理由不使用 CSS 选择器来设置第一个和最后一个元素的样式,而不是尝试将自定义类附加到它们?不要使用基于 alpha 或 omega 的样式,而是使用 first-child 和 last-child。

http://www.quirksmode.org/css/firstchild.html

【讨论】:

  • 我可能有多行,所以我必须创建一个内容 div 来包装每一行,以便定义该行中的第一个和最后一个子项(这会导致我回到需要一个 int多变的)。我明白你在说什么,这是我会尝试探索的东西。
  • 我们很清楚,您有多个行和多个列。为什么这不是一张桌子? ;)
【解决方案3】:
//this gets you both the item (myItem.value) and its index (myItem.i)
@foreach (var myItem in Model.Members.Select((value,i) => new {i, value}))
{
    <li>The index is @myItem.i and a value is @myItem.value.Name</li>
}

关于我的博客文章的更多信息 http://jimfrenette.com/2012/11/razor-foreach-loop-with-index/

【讨论】:

  • 感谢使用 LINQ。
  • 非常好和雄辩。 LINQ 令人印象深刻的是它可以在一行简单的代码中完成多少操作
【解决方案4】:
 @{int i = 0;}
 @foreach(var myItem in Model.Members)
 {
     <span>@i</span>
     @{i++;
      }
 }

// 使用@{i++ 增加值}

【讨论】:

  • 同意。正是我需要的
  • @(i++) 更紧凑:)
  • @(i++) 将显示为文本。在上面的代码中,会更好,但如果不需要显示,应该是i++;
  • 这个答案的问题是,如果页面上有多个 foreach 循环,则必须为每个循环声明一个新变量,而不是每次都使用 i。
  • i++;使用 @{i++;} 增加的所有内容都会给您带来问题。正如 Lee 所说,如果要在同一页面上多次使用它,那么解决方案将不起作用。
【解决方案5】:

IndexOf 在这里似乎很有用。

@foreach (myItemClass ts in Model.ItemList.Where(x => x.Type == "something"))
    {
       int currentIndex = Model.ItemList.IndexOf(ts);
       @Html.HiddenFor(x=>Model.ItemList[currentIndex].Type)

...

【讨论】:

    【解决方案6】:

    或者你可以简单地这样做:

    @foreach(var myItem in Model.Members)
    {    
        <span>@Model.Members.IndexOf(myItem)</span>
    }
    

    【讨论】:

    • @RicardoFontana 您始终可以使用“ToList()”方法。此外,最初的问题是关于 List&lt;T&gt;
    • 糟糕的答案。如果您在列表中有骗子,将无法正常工作。非常慢,因为它在每次迭代时搜索列表。周围都很糟糕。
    • @jpmc26 感谢您指出重复项目问题。我只关注这个问题。没有提到重复。
    【解决方案7】:

    非常简单:

         @{
             int i = 0;
             foreach (var item in Model)
             {
              <tr>
              <td>@(i = i + 1)</td>`
              </tr>
             }
          }`
    

    【讨论】:

    • 这个答案的问题是假设值显示在表格中。而且 i++ 它比 i = i+1; 更好、更有效。在这种情况下它对某人很有用,但这里有些人有点太挑剔了。
    【解决方案8】:

    以上所有答案都需要视图中的逻辑。视图应该是愚蠢的并且包含尽可能少的逻辑。为什么不在您的视图模型中创建与列表中的位置相对应的属性,例如:

    public int Position {get; set}
    

    在您的视图模型构建器中,您设置位置 1 到 4。

    但是 .. 甚至还有更清洁的方法。为什么不让 CSS 类成为你的视图模型的属性呢?因此,您只需执行以下操作,而不是部分中的 switch 语句:

    <div class="@Model.GridCSS">
    

    将 switch 语句移动到您的视图模型构建器并在那里填充 CSS 类。

    【讨论】:

      【解决方案9】:

      如果您想在您的视图中的 foreach 循环中计算来自模型的引用(即:客户端将地址作为引用,因此您想计算客户端将存在多少地址),例如:

       @foreach (var item in Model)
                              {
                                  <tr>
                                      <td>
                                          @Html.DisplayFor(modelItem => item.DtCadastro)
                                      </td>
      
                                      <td style="width:50%">
                                          @Html.DisplayFor(modelItem => item.DsLembrete)
                                      </td>
                                      <td>
                                          @Html.DisplayFor(modelItem => item.DtLembrete)
                                      </td>
                                      <td>
                                          @{ 
                                              var contador = item.LembreteEnvolvido.Where(w => w.IdLembrete == item.IdLembrete).Count();
                                          }
                                          <button class="btn-link associado" data-id="@item.IdLembrete" data-path="/LembreteEnvolvido/Index/@item.IdLembrete"><i class="fas fa-search"></i> @contador</button>
                                          <button class="btn-link associar" data-id="@item.IdLembrete" data-path="/LembreteEnvolvido/Create/@item.IdLembrete"><i class="fas fa-plus"></i></button>
                                      </td>
                                      <td class="text-right">
                                          <button class="btn-link delete" data-id="@item.IdLembrete" data-path="/Lembretes/Delete/@item.IdLembrete">Excluir</button>
                                      </td>
                                  </tr>
                              }
      

      按照编码做:

      @{ var contador = item.LembreteEnvolvido.Where(w => w.IdLembrete == item.IdLembrete).Count();}
      

      并像这样使用它:

      <button class="btn-link associado" data-id="@item.IdLembrete" data-path="/LembreteEnvolvido/Index/@item.IdLembrete"><i class="fas fa-search"></i> @contador</button>
      

      ps:不要忘记在 DbContext 内部的引用中添加 INCLUDE,例如,您的 Index 操作控制器,以防这是一个 IEnumerable 模型。

      【讨论】:

        【解决方案10】:

        您也可以使用解构和元组并尝试这样的事情:

        @foreach (var (index, member) in @Model.Members.Select((member, i) => (i, member)))
        {
          <div>@index - @member.anyProperty</div>
        
          if(index > 0 && index % 4 == 0) { // display clear div every 4 elements
              @: <div class="clear"></div>
          }
        }
        

        有关更多信息,您可以查看此link

        【讨论】:

          【解决方案11】:

          我更喜欢使用这种扩展方法:

          public static class Extensions
          {
              public static IEnumerable<(T item, int index)> WithIndex<T>(this IEnumerable<T> self)
                  => self.Select((item, index) => (item, index));
          }
          

          来源:

          https://stackoverflow.com/a/39997157/3850405

          剃须刀:

          @using Project.Shared.Helpers 
          
          @foreach (var (item, index) in collection.WithIndex())
          {
          <p>
              Name: @item.Name Index: @index
          </p>
          }
          

          【讨论】:

            猜你喜欢
            • 2012-06-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-09-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多