Tag-хэлперы в ASP.NET Core MVC. Асинхронные операции в tag-хэлперах

В предыдущей части мы рассмотрели простой пример собственного tag-хэлпера для вывода дня недели. При этом, tag-хэлперы могут содержать внутри себя другие tag-хэлперы, обращаться (как и любые другие классы) к данным содержащимся, например, в базе данных и так далее. В таких случаях мы можем использовать асинхронные операции в tag-хэлперах.

Пример асинхронной операции в tag-хэлпере

Для демонстрации примера воспользуемся нашим tag-хэлпером DayTagHelper из предыдущей части, который на данный момент имеет следующий вид:

using Microsoft.AspNetCore.Razor.TagHelpers;

namespace AspNetMvcTagCreate.TagHelpers
{
    public class DayTagHelper: TagHelper
    {
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "div";
            output.Content.SetContent($"Сегодня {DateTime.Now:dddd}");
        }
    }
}

Например, мы хотим, чтобы пользователю выводился не только день недели, но и, например, дата, номер дня в году и т.д. При этом, нам необходимо предусмотреть возможность вывода различной информации в зависимости от того, в каком представлении используется tag-хэлпер. Например, на главной странице мы хотим видеть всю информацию, а на второстепенных — только дату или только день в году и т.д. Таким образом, можно представить примерно следующую схему использования будущего tag-хэлпера:

<родительский_тэг>
  <дочерни_тэг_1></дочерни_тэг_1> 
  <дочерни_тэг_2></дочерни_тэг_2> 
  ...
  <дочерни_тэг_N></дочерни_тэг_N> 
</родительский_тэг>

Родительский тэг будет использовать асинхронную операцию для вывода всех дочерних тегов. Приступим к разработке. Для начала, создадим ещё один tag-хэлпер, который будет выводить номер дня в году:

using Microsoft.AspNetCore.Razor.TagHelpers;

namespace AspNetMvcTagCreate.TagHelpers
{
    public class DayNumberTagHelper: TagHelper
    {
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "div";
            output.Content.SetContent($"Номер дня в году {DateTime.Now.DayOfYear}");
        }
    }
}

Использоваться этот tag-хэлпер может также, как и предыдущий за одним исключением — так как название класса состоит из двух слов (исключая суффикс TagHelper), то есть DayNumber, то в разметке представления такой тэг будет выглядеть как <day-number>.

Теперь у нас есть два tag-хэлпера, которыми мы можем воспользоваться по отдельности, например, так:

<day></day>
<day-number></day-number>

Но мы продолжим разработку и теперь создадим tag-хэлпер, который будет выводить необходимую информацию по дате. Назовем его DayInfoTagHelper. Этот tag-хэлпер будет выполнять асинхронную операцию:

using Microsoft.AspNetCore.Razor.TagHelpers;

namespace AspNetMvcTagCreate.TagHelpers
{
    public class DayInfoTagHelper: TagHelper
    {
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            var childContent = await output.GetChildContentAsync();
            string content = "<h3>День недели</h3>";
            output.TagName = "div";
            content += childContent.GetContent();
            output.Content.SetHtmlContent(content);            
        }
    }
}

Отметим несколько отличий этого tag-хэлпера от предыдущих.

Во-первых, мы использовали асинхронный метод ProcessAsync() для вывода содержимого тэга. Если в tag-хэлпере будут определены оба метода — и Process() и ProcessAsync(), то предпочтение будет отдаваться именно асинхронному методу.

Во-вторых, в самой первой строке мы вызвали ещё один асинхронный метод output.GetChildContentAsync(), который возвращает объект, содержащий сгенерированную разметку всех дочерних элементов tag-хэлпера.

В-третьих, если tag-хэлпер содержит дочерние элементы, то содержимое дочерних элементов в виде обычной строки будет добавлено к выводу tag-хэлпера, для чего мы используем метод GetContent() дочерних элементов:

content += childContent.GetContent();

В-четвертых, так как для создания разметки tag-хэлпера мы использовали html-разметку (тэг заголовка h3), то для корректного вывода содержимого tag-хэлпера мы воспользовались методом SetHtmlContent():

output.Content.SetHtmlContent(content);

Теперь мы можем воспользоваться нашими tag-хэлперами следующим образом:

<day-info>
    <day></day>
    <day-number></day-number>
</day-info>

и получить следующий вывод:

Более того, теперь внутри тега мы можем создавать и такое содержимое:

<day-info>
    <strong>Инфа 100%</strong>
    <day></day>
    <day-number></day-number>
</day-info>

и получить следующее:

 

Таким образом, на текущий момент, структура нашего проекта выглядит следующим образом:

Мы создали три tag-хэлпера, один из которых использует асинхронную операцию для вывода содержимого дочерних tag-хэлперов.

Итого

Асинхронные операции в tag-хэлперах используются, в том числе, для вывода содержимого дочерних tag-хэлперов. Для асинхронного вывода используется метод ProcessAsync() и, при этом, если tag-хэлпер содержит оба метода — Process() и ProcessAsync(), то при генерации разметки представления предпочтение будет отдаваться асинхронной операции.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии