Я долго ломал голову, как лучше перевести выражение Partial View. Если попытаться дословно, то будет "частичные представления". Если попытаться чуть с большим смыслом, то у меня родился вариант "маленькие представления". Смысл Partial View – это возможность отрисовать часть страницы. У меня прямо ступор был минут на 10, потому что не мог начать писать эту главу и все думал, как же назвать ее.
Поломав немного голову, я решил не переводить термин Partial View дословно, а назвать его по смыслу – встраиваемые представления.
В MVC мы уже знаем, что есть такое понятие шаблона. Внутри шаблона мы можем вызвать RenderBody(), чтобы отрисовать текущую страницу. А что если на странице будет еще какой-то повторяющийся элемент? Например, у меня на сайте в разделе блога, в разделе статей и в книгах (в отдельных главах пока еще не сделал) можно оставлять комментарии. Это совершенно разные страницы, но они используют один и тот же функционал – отображение страниц и отображение формы для сохранения комментариев. Это как-бы регион, внутри страницы, который желательно было бы реализовать отдельно и просто потом вставлять в нужные страницы.
Вот именно это и делают встраиваемые страницы (Partial View). Они не предназначены для того, чтобы отрисовывать все содержимое. Вместо этого такие представления отвечают за логику какой-то части на страницы, и вы это частичное представление встраиваете куда-угодно. Получается, что термин частичное представление тоже верный и можно было перевести дословно? Да! Но мне все же встраиваемое представление почему-то нравится больше. Моя книга, что хочу, то и делаю, поэтому буду использовать такой термин.
Частичные представления – это такие же представления, как и у страниц, только когда фреймворк рендерит их, он не отображает шаблон, потому что он там не нужен.
Как мы уже определились, представления встраиваемые и встраиваться они могут как в файл шаблона, так и в файл представления страницы. Да даже в файл другого встраиваемого представления. В любой cshtml файл (а встраиваемые представления тоже будут иметь такое же расширение) вы можете встроить другое представление. И делается это командой:
@Html.Partial("ИмяФайла", Модель)
Еще один вариант использования частичных представлений – отображение элементов списка. Опять же вернемся к моему сайту. В разделах Блог можно увидеть постранично в 10 элементов мои заметки. Каждая заметка – это отдельное частично представление, поэтому если бы сайт был написан на C#, то страница блога могла выглядит так:
foreach (var blogItem in blogItems) {
}
Так как у меня сайт написан на PHP, то он так не выглядит, но идея все же такая же.
Но здесь мы говорим про C# и .NET Core поэтому примерно то же самое накидаем на этом фреймворке.
Сначала создадим встраиваемое представление. Его можно поместить в папку Shared, или в ту же папку, из которой мы будем рисовать этот файл. Я помещу его в Views/razortest. Для этого щелкаем правой кнопкой мышки по этой папке и создаем новый файл. Раньше в VS кажется был специальный шаблон, но в версии для Mac я его не увидел. Ну и фиг с ним, это всего лишь шаблоны, мы можем выбрать тут совершенно любой тип файла, главное дать правильное расширение и правильный контент.
Для partial view рекомендуется ставить вначале имени префикс в виде символа подчеркивания. Это не обязательно, а рекомендация, чтобы визуально отличить файлы полноценных представлений от частичных или каких-либо системных, как мы уже делали с _Layout.cshtml.
Итак, в окне выбора шаблона для файла я выбрал MVC View Page (просто захотелось так) и в качестве имени файла указал: _Item.cshtml. VS создаст для нас файл, содержимое которого можно очистить на фиг.
Вместо этого напишем следующий код:
@model MyWebSite.Model.Person
Если вы внимательно читали предыдущие главы, то в этом файле для вас нет совершенно ничего нового. В самом начале мы задаем тип модели, который ожидаем во время вызова представления, а потом идет микс HTML и C# кода, в котором я просто отображаю имя и фамилию.
У нас есть частичное представление, которое мы можем куда-нибудь внедрить, так давайте это и сделаем. Из предыдущих примеров у меня остался контроллер RazortestController и в нем есть метод List, который отображал список людей. Иы использовали этот пример, когда я показывал различные варианты циклов в представлениях. Давайте перепишем этот пример с использованием встраиваемого представления. Контроллер остается тем же, меняем только отображение, поэтому открываем файл List.cshtml и в нем все содержимое заменяем на следующее:
@model MyWebSite.Model.Person[]
Покажем список с помощью Partial View:
@foreach (var p in Model) { @Html.Partial("_Item", p); }
Теперь весь код сводиться к циклу, который перебирает всех людей из модели и для каждого человека вызывается отображение частичного представления – мы встраиваем его в текущую позицию с помощью:
@Html.Partial("_Item", p);
Первый параметр – это имя файла, а второй – модель типа Person. Именно ее же ожидает наше представление.
Преимущество заключается в том, что теперь _Item работает как виджет. Мы можем отображать его на любой странице сайта, вызывать его откуда угодно. И если в определенный момент захочется поменять внешний вид этого виджета (карточки человека), то достаточно поменять ее в файле _Item.cshtml и изменения вступят в силу везде.
Кстати, использование метода Partial немного старый подход и сейчас MS рекомендует использовать асинхронную версию PartialAsync, которая защищена от блокировок.
@await Html.PartialAsync("_Item", p)
Первая версия тоже будет работать, просто во время компиляции будет отображаться предупреждение и это предупреждение дается не просто так, используйте асинхронную версию.
Есть еще пара методов RenderPartial и RenderPartialAsync. Отличие этих двух версий в том, что они вызывают отрисовку представления, но при этом не возвращают его в качестве результата, а отображают его.
Посмотрим на следующие два примера:
@await Html.PartialAsync("_Item", new MyWebSite.Model.Person() { FirstName = "Михаил", LastName = "Фленов" }) @{ await Html.RenderPartialAsync("_Item", new MyWebSite.Model.Person() { FirstName = "Михаил", LastName = "Фленов" }); }
В первом случае вызывается метод PartialAsync, который возвращает результат отрисовки и мы его отображаем за счет того, что ставим впереди символ @. Точно так же мы отображаем и имя, когда пишем @Model.FirstName. Одиночный символ @ как раз используется для отображения.
Второй метод RenderPartialAsync ничего не возвращает, поэтому нельзя написать:
@await Html.RenderPartialAsync(. . . .
Этот финт закончится ошибкой. Вместо этого я перехожу в режим кода @{, потом вызываю RenderPartialAsync который ничего не вернет, но зато отобразит.
Как можно использовать эту разницу? Допустим, что вы хотите вызвать представление, но не хотите его отображать в текущей позиции, а сохранить результат и потом еще и обработать. Такое возможно:
@{ var result = Html.Partial("_Item", new MyWebSite.Model.Person() { FirstName = "Михаил", LastName = "Фленов" }); }
Здесь мы не отображаем представление, а вызываем его и результат рендеринга сохраняем в переменной result. Теперь эту переменную можно как-то еще обработать, передать кому-нибудь или даже просто отобразить, если написать @result.
Мне сначала казалось, что тема достаточно простая и я ее раскидаю быстро, но получилось уже аж на три страницы Word, поэтому закругляюсь до следующей главы, постараюсь написать на следующей неделе.