Для управления выводом tag-хелпера применяется объект TagHelperOutput, который передается в качестве параметра в метод Process/ProcessAsync tag-хелпера. Его свойства позволяют управлять генерацией элемента html:
TagName: указывает, какой элемент html будет создаваться вместо тега хелпера
TagMode: устанавливает формат создаваемого элемента (с одним или с двумя тегами)
Attributes: представляет коллекцию атрибутов, устанавливаемых у создаваемого элемента html
Content: представляет содержимое генерируемого элемента html в виде объекта TagHelperContent
PreContent: представляет содержимое, которое устанавливается перед создаваемым элементом html
PostContent: представляет содержимое, которое устанавливается после создаваемого элемента html
PreElement: представляет html-элемент, который добавляется перед создаваемым элементом html
PostElement: представляет html-элемент, который добавляется после создаваемого элемента html
Элементы html могут состоять из двух тегов (открывающего и закрывающего), либо из одного тега (открывающегося или самозакрывающегося). С помощью свойства TagMode мы можем регулировать закрытие элемента. Оно принимает одно из значений перечисления TagMode:
StartTagAndEndTag
: элемент имеет оба тега
SelfClosing
: элемент содержит самозакрывающийся тег
StartTagOnly
: элемент имеет только открывающий тег
По умолчанию при создании элемента применяется тот же режим закрытия тега, который использовался при его использовании. Например, если мы не устанавливаем содержимое внутри tag-хелпера, то нет смысла определять для него оба тега. Например, определим следующий tag-хелпер:
public class TimerTagHelper : TagHelper { public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; output.TagMode = TagMode.StartTagAndEndTag; output.Content.SetContent($"Текущее время: {DateTime.Now.ToString("HH:mm:ss")}"); } }
И теперь мы сможем использовать только один тег:
<timer />
Для управления контентом применяется свойство Content, представляющее объект TagHelperContent, у которого можно выделить следующие методы:
SetContent(text): устанавливает текстовое содержимое элемента
SetHtmlContent(html): устанавливает вложенный html-код элемента
Append(text): добавляет к текстовому содержимому элемента некоторый текст
AppendHtml(html): добавляет к внутреннему коду элемента некоторый код html
Clear(): очищает элемент
Так, выше уже использовался метод output.Content.SetContent()
.
С помощью дополнительных свойств PreElement/PostElement/PreContent/PostContent, который также представляют объект TagHelperContent, можно управлять контентом вокруг элемента. Например, изменим класс хелпера:
public class TimerTagHelper : TagHelper { public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; output.TagMode = TagMode.StartTagAndEndTag; // элемент перед тегом output.PreElement.SetHtmlContent("<h4>Дата и время</h4>"); // элемент после тега output.PostElement.SetHtmlContent($"<div>Дата: {DateTime.Now.ToString("dd/MM/yyyy")}</div>"); output.Content.SetContent($"Время: {DateTime.Now.ToString("HH:mm:ss")}"); } }
В итоге в данном случае тег <timer />
будет преобразован в следующий набор элементов:
<h4>Дата и время</h4> <div>Время: 20:34:42</div> <div>Дата: 07.12.2019</div>
Свойство Attributes позволяет устанавливать атрибуты генерируемого элемента. Оно представляет объект TagHelperAttributeList, который управляет атрибутами с помощью ряда методов. Некоторые из них:
Add(string name, object value): добавляет атрибут с именем name и значением value
RemoveAll(string name): удаляет все атрибуты с именем name
SetAttribute(string name, object value): устанавливает для атрибута с именем name значение value
Clear(): удаляет все атрибуты
Для примера установим стиль и класс элемента:
public class TimerTagHelper : TagHelper { public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; output.TagMode = TagMode.StartTagAndEndTag; output.Attributes.SetAttribute("style", "color:red;"); output.Attributes.SetAttribute("class", "timer"); output.Content.SetContent($"{DateTime.Now.ToString("HH:mm:ss")}"); } }
В итоге из тега:
<timer />
сгенерирована следующая разметка:
<div style="color:red;" class="timer">20:57:26</div>
Мы можем не только управлять атрибутами создаваемых html-элементов, но и определять для тег-хелперов свои атрибуты. Через атрибуты мы можем передать из вне в класс хелпера некоторые значения. В самом классе можно получить переданные значения с помощью публичных свойств. Например, добавим возможность установки цвета элемента и возможность выбора, надо ли выводить секунды:
public class TimerTagHelper : TagHelper { public bool SecondsIncluded { get; set; } public string? Color { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { var now = DateTime.Now; var time = String.Empty; if (SecondsIncluded) // если true добавляем секунды time = now.ToString("HH:mm:ss"); else time = now.ToString("HH:mm"); output.TagName = "div"; output.TagMode = TagMode.StartTagAndEndTag; // устанавливаем цвет, если свойство Color не равно null if(Color != null) output.Attributes.SetAttribute("style", $"color:{Color};"); output.Content.SetContent(time); } }
Используем этот хелпер в представлении:
<timer color="navy" seconds-included="true" /> <timer color="#0984e3" seconds-included="true" /> <timer color="#ff7675" /> <timer />
Во время выполнения приложения из атрибутов будут передаваться значения соответствующим свойствам. Соответствие идет по имени.
Но надо отметить, что если атрибут тега или сам тег в названии содержит дефисы в качестве разделителей, то название соответствующего тегу
свойства состоит из нескольких частей и каждая из этих частей начинается с заглавной буквы. Например, атрибуту seconds-included
будет соответствовать свойство SecondsIncluded
.
Кроме того, мы можем не указывать атрибуты в теге, тогда свойства хелпера получат значения по умолчанию, как в случае выше. Но если в случае выше это не критично, то в других конкретных случаях это может сыграть важную роль, и на этот случае можно проверять значения свойств перед использованием.
Кроме свойств TagHelperOutput имеет еще ряд методов, которые позволяют управлять выводом. Среди них надо отметить метод SuppressOutput(), который позволяет не обрабатывать тег. То есть при применении этого метода тег не будет обрабатываться, и для него не будет создаваться никакой html-разметки на веб-странице. Так, изменим класс хелпера следующим образом:
public class TimerTagHelper : TagHelper { public bool Condition { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { if (!Condition) { output.SuppressOutput(); } else { output.TagName = "div"; output.TagMode = TagMode.StartTagAndEndTag; output.Content.SetContent($"{DateTime.Now.ToString("HH:mm:ss")}"); } } }
Здесь добавляется свойство Condition, которое хранит логическое значение true или false. А в методе Process в зависимости от его значения
применяется метод output.SuppressOutput()
, который прекращает обработку тега.
В этом случае в представлении мы можем определить следующий код:
<timer condition="false" /> <timer condition="true" />
Здесь свойству Condition соответствует атрибут condition, который принимает значение true или false. И поскольку в первом случае в
атрибут condition передано значение false, для этого тега в классе будет применяться метод output.SuppressOutput()
,
поэтому вместо этого тега на веб-странице мы ничего не увидим.
Кроме простых свойств типа int или string в хелпер можно передавать сложные объекты. Например:
using Microsoft.AspNetCore.Razor.TagHelpers; namespace MvcApp.TagHelpers { public class TimerTagHelper : TagHelper { public StyleInfo? Style { get; set; } public override void Process(TagHelperContext context, TagHelperOutput output) { output.TagName = "div"; output.TagMode = TagMode.StartTagAndEndTag; // формируем стиль string style = ""; if (Style?.Color != null) style = $"color:{Style.Color};"; if (Style?.FontSize != null) style = $"{style}font-size:{Style.FontSize}px;"; if (Style?.FontFamily != null) style = $"{style}font-family:{Style.FontFamily};"; output.Attributes.SetAttribute("style", style); output.Content.SetContent($"{DateTime.Now.ToString("HH:mm:ss")}"); } } public class StyleInfo { public string? Color { get; set; } public int? FontSize { get; set; } public string? FontFamily { get; set; } } }
Здесь хелпер хранит ссылку на объект StyleInfo, которые инкапсулирует стилевые свойства создаваемого элемента. Далее в представлении мы можем передать значения для этого свойства:
@using MvcApp.TagHelpers @*пространство имен класса StyleInfo*@ @addTagHelper *, MvcApp <timer style='new StyleInfo{Color="#c0392b", FontFamily="Verdana", FontSize=18}' /> <timer style='new StyleInfo{Color="#2980b9", FontFamily="Arial", FontSize=18}' />