循环使用剃刀中的列表并在项目之间添加分隔符

Mar*_*ius 12 asp.net-mvc razor

我有一个项目列表,我想在剃须刀视图中输出.在每个项目之间我想添加一个分隔线,如下所示:

item1 | item2 | item3
Run Code Online (Sandbox Code Playgroud)

循环项目的最简单方法是使用foreach:

@foreach(var item in Model.items){
  <span>@item.Name</span> | 
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这会在列表末尾添加一个额外的分隔线.是否有一种简单的方法可以跳过最后一个分隔线?

Oli*_*ver 20

你可以使用string.Join:

@Html.Raw(string.Join("|", model.Items.Select(s => string.Format("<span>{0}</span>", s.Name))))
Run Code Online (Sandbox Code Playgroud)

使用string.Join否定需要检查最后一项.

您可以将其与Razor @helper方法混合使用以获得更复杂的标记:

@helper ComplexMarkup(ItemType item)
{ 
    <span>@item.Name</span>
}

@Html.Raw(string.Join("|", model.Items.Select(s => ComplexMarkup(s))))
Run Code Online (Sandbox Code Playgroud)

您甚至可以创建一个帮助方法来抽象Html.Raw()string.Join()调用:

public static HtmlString LoopWithSeparator
    (this HtmlHelper helper, string separator, IEnumerable<object> items)
{
    return new HtmlString
          (helper.Raw(string.Join(separator, items)).ToHtmlString());
}
Run Code Online (Sandbox Code Playgroud)

用法:

@Html.LoopWithSeparator("|",  model.Items.Select(s => ComplexMarkup(s)))
Run Code Online (Sandbox Code Playgroud)


Mar*_*ius 5

结合这里的其他答案和这篇关于内联模板的文章,我想出了这个辅助方法,可以将其放入扩展类中:

public static HelperResult Join<T>(this IEnumerable<T> list, Func<T, HelperResult> template, Func<T, HelperResult> separator)
{
    var first = true;
    var result = new HelperResult(writer =>
    {
        foreach (var item in list)
        {
            if (first == false)
                separator(item).WriteTo(writer);
            first = false;
            template(item).WriteTo(writer);
        }
    });

    return result;
}
Run Code Online (Sandbox Code Playgroud)

那么使用它的方法就是

@Model.ListOfItems.Join(
    @<a href="@item.Href">
        @item.Name
    </a>, 
    @<text> | </text>)
Run Code Online (Sandbox Code Playgroud)

这支持项目和分隔符中的 html。