В предыдущей части мы рассмотрели простой пример собственного 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()
, то при генерации разметки представления предпочтение будет отдаваться асинхронной операции.