Делегаты шаблонов Razor

Недавно в блоге Фила Хаака (Phil Haack) была опубликована интересная заметка. В ней шла речь о достаточно необычной возможности движка представлений Razor.

Эту идею подсказал Дэвид Фаулер (David Fowler). Как же что же такое делегаты шаблонов Razor (Templated Razor Delegates)? Давайте начнем с примера кода:

@{
  Func<dynamic, object> b = @<strong>@item</strong>;
}
<span>This sentence is @b("In Bold").</span>

Как можно догадаться, текст "In Bold" будет выведен жирным шрифтом. Обратите внимание, что создаваемый делегат будет иметь тип Func<dynamic, HelperResult>. Кроме того, в коде присутствует магическое значение @item. Это, по сути, единственный параметр делегата, но шаблон может обращаться к нему столько раз, сколько необходимо.

Пример выше достаточно простой. Почему бы не попробовать его использовать при создании помощника (helper). Давайте перейдем к примеру, который действительно может быть полезен в работе. Это будет метод, который выводит список, используя предоставленный шаблон:

public static class RazorExtensions
{
    public static HelperResult List<T>(this IEnumerable<T> items,
      Func<T, HelperResult> template)
    {
        return new HelperResult(writer => {
            foreach (var item in items) {
                template(item).WriteTo(writer);
            }
        });
    }
}

Метод List() принимает в качестве параметра шаблон Razor. Использовать его можно так:

@{
  var items = new[] { "one", "two", "three" };
}

<ul>
@items.List(@<li>@item</li>)
</ul>

Как уже было отмечено выше, аргумент метода (@<li>@item</li>) будет представлен как делегат типа Func<dynamic, HelperResult>.

Самое интересное заключается в том, что созданный метод хорошо подходит для повторного использования в разных сценариях. Давайте вместо списка выведем таблицу:

@{
    var comics = new[] { 
        new ComicBook {Title = "Groo", Publisher = "Dark Horse Comics"},
        new ComicBook {Title = "Spiderman", Publisher = "Marvel"}
    };
}

<table>
@comics.List(
  @<tr>
    <td>@item.Title</td>
    <td>@item.Publisher</td>
  </tr>)
</table>

По материалам заметки "Templated Razor Delegates".

Комментарии (1) -

Тема конечно покрыта мхом, но все же вопрос.
А если в шаблоне нужно использовать какой-либо свой хелпер? Можно и если да, то как тогда его использовать?

Pingbacks and trackbacks (1)+

Добавить комментарий