При разработке приложения Blazor не всегда бывает известно то, какие атрибуты должен содержать тот или иной элемент на странице. Например, в зависимости от каких-то внешних данных мы должны менять стиль элемента на форме или добавлять/добавлять какие-либо атрибуты и так далее. В Blazor имеется возможность передавать произвольный набор атрибутов компонентам.
Директива @attributes
Директива @attributes
позволяет компоненту обрабатывать необъявленные атрибуты. Эта директива может оказаться полезной при определении компонента, который создает элемент разметки, поддерживающий разнообразные настройки. Например, может оказаться довольно утомительным по отдельности определять атрибуты для каждого элемента<input>
на форме.
Передача набора атрибутов компоненту осуществляется с помощью словаря Dictionary
. Рассмотрим следующим пример использования директивы @attributes
:
@page "/attributes" <input id="input1" maxlength="@maxlength" placeholder="@placeholder" required="@required" size="@size" /> <input id="input2" @attributes="InputAttributes" /> @code { private string maxlength = "10"; private string placeholder = "Не более 10 символов"; private string required = "required"; private string size = "50"; private Dictionary<string, object> InputAttributes { get; set; } = new Dictionary<string, object>() { { "maxlength", "10" }, { "placeholder", "Не более 10 символов" }, { "required", "required" }, { "size", "50" } }; }
Здесь для элемента input
с id="input1"
каждый атрибут прописывается отдельно, а для input
с id="input2"
используется словарь Dictionary<string, object> InputAttributes
. В результате рендеринга мы увидим в окне браузера два абсолютно одинаковых элемента:
<input id="input1" maxlength="10" placeholder="Не более 10 символов" required="required" size="50" /> <input id="input2" maxlength="10" placeholder="Не более 10 символов" required="required" size="50" />
но, при этом, во втором случае код визуальной части стал лаконичнее.
Передача атрибутов от родительского компонента дочернему
Для того, чтобы компонент Blazor мог принимать набор произвольных атрибутов от родительского компонента, необходимо определить параметр компонента с помощью свойства CaptureUnmatchedValues
, имеющего значение true
:
[Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object> InputAttributes { get; set; }
Свойство CaptureUnmatchedValues
в [Parameter]
позволяет параметру соответствовать всем атрибутам, которые не соответствуют никакому другому параметру. Например, попробуем передать в input
c id="input2"
из примера выше произвольный набор атрибутов, который определим на главной странице приложения Blazor Server:
Код страницы Index.razor
:
@page "/" <PageTitle>Index</PageTitle> <h1>Hello, world!</h1> Welcome to your new app. <SurveyPrompt Title="How is Blazor working for you?" /> <h3>Здесь компонент с произвольным набором атрибутов</h3> <Component @attributes="Attributes"/> @code{ @*Словарь атрибутов*@ private Dictionary<string, object> Attributes { get; set; } = new Dictionary<string, object>() { { "maxlength", "20" }, { "placeholder", "Не более 20 символов" }, { "required", "required" }, { "size", "20" } }; }
Код дочернего компонента:
@page "/attributes" <input id="input2" @attributes="InputAttributes" maxlength="5" /> @code { [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object> InputAttributes { get; set; } }
maxlength
у input
— он равен 5
, в то время, как из родительского компонента мы пытаемся передать для этого атрибута значение 20
.Результат будет следующим:
<input id="input2" placeholder="Не более 20 символов" required="required" size="20" maxlength="5" />
Значение атрибут maxlength
осталось неизменным, так как этот атрибут уже был прописан у компонента. При этом, все другие атрибуты из словаря были применены. При использовании свойства CaptureUnmatchedValues
следует отметить следующее:
- компонент может определять только один параметр с
CaptureUnmatchedValues
. - тип свойства, используемый с
CaptureUnmatchedValues
, должен бытьDictionary<string, object>
. Также допускается использоватьIEnumerable<KeyValuePair<string, object>>
илиIReadOnlyDictionary<string, object>
Итого
Для передачи компоненту Blazor произвольного набора атрибутов используется директива @attributes
, со значением Dictionary<string, object>
. Чтобы дочерний компонент мог принимать набор атрибутов от родительского, необходимо использовать свойство CaptureUnmatchedValues = true
у атрибута [Parameter]
свойства компонента.