Компоненты представления: добавление логики в частичные представления¶
Компоненты представления (view components) — отдельные сущности, позволяющие инкапсулировать как логику отрисовки, так и бизнес-логику для отображения небольшого раздела страницы. Они вызываются непосредственно из представления Razor, а не в ответ на HTTP-запрос.
Компоненты представления в сравнении с Razor Components и Blazor
В Blazor есть две модели программирования — на стороне клиента и стороне сервера — и в обоих используются компоненты Blazor (официально названные компонентами Razor). Их не следует путать с компонентами представления — они не взаимодействуют с тег-хелперами или компонентами представления, и их сложно комбинировать с формами Razor Page.
Однако при необходимости можно встроить компонент Blazor внутрь страницы Razor, как показано тут. Также можно использовать компоненты Blazor как способ заменить вызовы AJAX, как показано тут, в блоге автора.
Однако, если интерактивность на стороне клиента не нужна, лучше использовать компоненты представления. Дополнительная информация — в ещё одной записи из блога автора
Создадим специальный компонент представления для нашего приложения с рецептами, который будет отображать список ссылок на недавно созданные рецепты в случае, когда пользователь выполнил вход, и форму для входа в противном случае.
Совет
Используйте частичные представления для инкапсуляции отрисовки модели представления или её части; если же логика отрисовки требует доступ к БД или бизнес-логике, или если раздел логически отличается от содержимого главной страницы, желательно использовать компонент представления.
Компоненты представления вызываются непосредственно из представлений и макетов Razor с использованием синтаксиса в стиле тег-хелпера с префиксом vc:
Специальные компоненты обычно реализуют, унаследовавшись от базового класса
ViewComponent и реализуют метод InvokeAsync(). Параметры, передаваемые в InvokeAsync(), соответствуют свойствам элемента тег-хелпера (с заменой camelCase на kebabCase):public class MyRecipesViewComponent: ViewComponent
{
private readonly RecipeService _recipeService;
private readonly UserManager<ApplicationUser> _userManager;
public MyRecipesViewComponent(
RecipeService recipeService, UserManager<ApplicationUser> userManager)
{
_recipeService = recipeService;
_userManager = userManager;
}
public async Task<IViewComponentResult> InvokeAsync(int numberOfRecipes)
{
if(!User.Identity.IsAuthenticated)
{
return View("Unauthenticated");
}
var userId = _userManager.GetUserId(HttpContext.User);
var recipes = await _recipeService.GetRecipesForUser(
userId, numberOfRecipes);
return View(recipes);
}
}
Для задания имени компонента представления можно использовать атрибут
[ViewComponent].Метод
InvokeAsync() должен вернуть Task<IViewComponentResult>; компоненты представления не могут возвращать коды состояния или перенаправления, они должны как-то визуализировать содержимое. Поэтому необходимо использовать либо метод View(), либо Content(), который кодирует содержимое в HTML и отображает его напрямую.Компоненты представления имеют доступ к
HttpContext и текущему запросу.Частичные представления для компонентов работают аналогично частичным представлениям Razor, но хранятся отдельно, в одном из следующих мест:
- Views/Shared/Components/ComponentName/TemplateName;
- Pages/Shared/Components/ComponentName/TemplateName.
Для нашего компонента необходимо два представления (используем папку Pages):
- Pages/Shared/Components/MyRecipes/Default.cshtml;
- Pages/Shared/Components/MyRecipes/Unauthenticated.cshtml.
Также при использовании компонентов представления необходимо помнить о следующем:
- классы компонентов представления должны быть открытыми, невложенными и неабстрактными;
- с ними нельзя использовать фильтры;
- можно использовать макеты, а также
@sections, как показано здесь, но данные секции не зависят от основного макета Razor; - компоненты представления изолированы от страницы Razor, на которой они отображаются;
- при использовании тег-хелпера
<vc:my-recipes>необходимо импортировать его в качестве специального тег-хелпера; - вместо использования синтаксиса тег-хелпера можно вызвать компонент представления напрямую из представления:
Дата создания : 27 октября 2022 г.