Как реализовать foreach делегат в бритве viewengine? - PullRequest
3 голосов
/ 22 февраля 2011

Следующий код работает для механизма просмотра веб-формы.

<% Model.Categories.ForEach(x => { %>
    <li><a href="#">@x.Name</a></li>
<% }) %>

Я написал приведенный выше код, как показано ниже:

@Model.Categories.ForEach(x => {
  <li><a href="#">@x.Name</a></li>
})

Но это не работает.

Кто-нибудь может подсказать, есть ли способ добиться этого с точки зрения бритвы?

Заранее спасибо.

Ответы [ 2 ]

7 голосов
/ 22 февраля 2011

Есть ли причина, по которой вам нужно это сделать?

@foreach(var x in Model.Categories) {
    <li><a href="#">@x.Name</a></li>
}

Выше делает то же самое, и более идиоматично.

Я не вижу способа вывести результат делегата .ForEach(), используя синтаксис Razor. Razor ожидает, что вызванные методы или вызванные свойства возвращают значение, которое затем передается в вывод представления. Поскольку .ForEach() ничего не возвращает, он не знает, что с ним делать:

Невозможно явно преобразовать тип 'void' в 'object'

Вы можете получить краткий индекс итератора примерно так:

@foreach (var item in Model.Categories.Select((cat, i) => new { Item = cat, Index = i })) {
   <li><a href="#">@x.Index - @x.Item.Name</a></li>
}

Если вы хотите определить это как метод расширения, а не анонимный тип, вы можете создать класс для хранения пары Item, Index и определить метод расширения для IEnumerable<T>, который yield отображает элементы в оригинальный перечислимый, завернутый в эту конструкцию.

public static IEnumerable<IndexedItem<T>> WithIndex<T>(this IEnumerable<T> input)
{ 
    int i = 0;
    foreach(T item in input)
        yield return new IndexedItem<T> { Index = i++, Item = item };
}

Класс:

public class IndexedItem<T>
{
    public int Index { get; set; }
    public T Item { get; set; }
}

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

@foreach(var x in Model.Categories.WithIndex()) {
    <li><a href="#">@x.Index - @x.Item.Name</a></li>
}
5 голосов
/ 13 марта 2011

Спасибо за вашу помощь. Я нашел, как реализовать делегатов в Razor, основываясь на следующей статье Фила Хаака. Делегированные шаблонные бритвы

Вот код расширения для IEnumerable:

public static HelperResult ForEachTemplate<TEntity>(
        this IEnumerable<TEntity> items, 
        Func<RowEntity<TEntity>, HelperResult> template)
{
    return new HelperResult(writer =>
               {
                   var index = 0;
                   foreach (var item in items)
                   {
                       template(new RowEntity<TEntity> { 
                               Index = index, 
                               Value = item }).WriteTo(writer);
                       index++;
                   }
               });
}

public class RowEntity<TEntity>
{
    public int Index { get; set; }
    public TEntity Value { get; set; }
}

Просмотр Модель:

// IEnumerable<Person>

public class Person
{
    public string Name { get; set; }
}

И использование методов этого расширения:

@Model.ForEachTemplate(@<p>Index: @item.Index Name: @Item.Value.Name</p>)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...