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


