2013-03-18 2 views
10

У меня есть список элементов, которые я хочу выводить в виде бритвы. Между каждым элементом я хочу, чтобы добавить разделительную линию, например:Цитирование по списку в бритве и добавление разделителя между элементами

item1 | item2 | item3 

Самый простой способ перебрать элементов является с Еогеасп:

@foreach(var item in Model.items){ 
    <span>@item.Name</span> | 
} 

К сожалению, это добавляет дополнительную разделительную линию в конце списка. Есть ли простой способ пропустить эту последнюю разделительную линию?

ответ

18

Вы можете использовать string.Join:

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

Использование string.Join исключает необходимость проверки наличия последнего элемента.

Вы можете смешать это с помощью метода Бритва @helper для более сложной разметки:

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

@Html.Raw(string.Join("|", model.Items.Select(s => ComplexMarkup(s)))) 

Можно даже создать вспомогательный метод для абстрагировать 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()); 
} 

Использование:

@Html.LoopWithSeparator("|", model.Items.Select(s => ComplexMarkup(s))) 
+0

+1 более элегантный, чем другие ... –

+0

Это кажется подходящим только для очень простых корпусов петли. – Marius

+0

Правда, см. Править для улучшения на этом фронте ... – Oliver

2

Не уверен, что это самый простой способ, или если это более элегантный способ, но вы могли бы что-то сделать;

@foreach (var item in Model.items){ 
    <span>@item.Name</span> @(Model.items[Model.items.Count - 1] != item ? "|" : "") 
} 

Таким образом, вы в основном проверки, чтобы увидеть, если item последний элемент в списке.

Не пробовал этот образец кода, поэтому вам может потребоваться его подправить.

2

Сохраните переменную счетчика и внутри цикла и проверьте, является ли это последним элементом или нет.

@{ int counter=0; } 
@foreach(var item in Model.items){ 
    counter++; 
    <span>@item.Name</span> 
    if(counter<Model.Items.Count) 
    { 
    @Html.Raw("|") 
    } 
} 

и короткая версия

@{ int counter=0; } 
@foreach(var item in Model.items){ 
    counter++; 
    <span>@item.Name</span> @(counter< Model.items.Count?"|":"") 
} 
+0

Это, как я бы это сделать, потому что я никогда не нашел способ, чтобы получить что-то вроде этого, чтобы работать: @for (INT I = 0; Model.items.Count; я ++) бы хотелось знаете, как это делается. – sanepete

2

Объединение другие ответы здесь с this article on inline templates, я придумал этот вспомогательный метод, который можно поставить в классе расширения:

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

способ использовать тогда было бы

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

Это поддерживает HTML в как элементы, так и разделитель.

Смежные вопросы