Передача набора произвольных параметров в компонент Razor

Возможно, что при разработке очередного компонента Razor вам потребуется, чтобы этот компонент изменял свое состояние или внешний вид в зависимости от каких-либо внешних параметров. В этом случае мы можем предусмотреть передачу набора произвольных параметров в компонент Razor.

Директива @attributes

Директива Razor @attributes позволяет компоненту обрабатывать необъявленные атрибуты. При этом, значение, передаваемое в @attributes должно быть объектом типа Dictionary<string, object>. Чтобы продемонстрировать как работает директива, воспользуемся приложением Blazor Hybrid из предыдущей части.

Исходный код из предыдущей части

Ниже представлены только изменения, которые были сделаны в шаблонном приложение Blazor Hybrid

Файл Components/SmartCounter.razor

<h3>@Title</h3>
<p>@ChildContent</p>
<br />
<p>Значение: @Count</p>
<button @onclick="IncrementCounter">Прибавить 1</button>
<button @onclick="DecrementCounter">Отнять 1</button>

@code {
    [Parameter, EditorRequired]
    public string Title { get; set; }

    [Parameter]
    public int Count { get; set; }

    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    private void IncrementCounter()
    {
        Count++;  
    }

    private void DecrementCounter()
    {
        Count--;
    }
}

Файл Home.razor

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SmartCounter Title="Smart-счётчик" Count="10">
    <b>Это текст для смарт-счётчика</b>
</SmartCounter>

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

Обратите внимание на кнопки — это обычные кнопки без всяких излишеств и украшений. Давайте воспользуемся директивой @attributes для назначения этим кнопкам ряда атрибутов bootstrap. Допишем код компонента следующим образом:

<h3>@Title</h3>
<p>@ChildContent</p>
<br />
<p>Значение: @Count</p>
<button @onclick="IncrementCounter" @attributes="buttonParams">Прибавить 1</button>
<button @onclick="DecrementCounter" @attributes="buttonParams">Отнять 1</button>

@code {
    Dictionary<string, object> buttonParams = new Dictionary<string, object>()
    {
       {"type", "button" },
       {"class", "btn btn-primary" }
    };

    [Parameter, EditorRequired]
    public string Title { get; set; }

    [Parameter]
    public int Count { get; set; }

    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    private void IncrementCounter()
    {
        Count++;  
    }

    private void DecrementCounter()
    {
        Count--;
    }
}

Здесь в C# коде компонента мы определили словарь атрибутов:

Dictionary<string, object> buttonParams = new Dictionary<string, object>()
{
   {"type", "button" },
   {"class", "btn btn-primary" }
};

Этот словарь мы назначили директиве @attributes каждой из кнопок:

<button @onclick="IncrementCounter" @attributes="buttonParams">Прибавить 1</button>
<button @onclick="DecrementCounter" @attributes="buttonParams">Отнять 1</button>

Запустим приложение и посмотрим на результат:

В html-код приложения кнопки будут выглядеть следующим образом:

При необходимости, мы можем передавать словарь произвольных атрибутов в дочерний компонент из родительского.

Передача набора произвольных параметров из родительского в дочерний компонент Razor

Чтобы передать набор произвольных параметров из родительского в дочерний компонент достаточно объявить параметр типа  в компоненте Dictionary<string, object> и передать ему значение в родительском компоненте. Например, перепишем SmartCounter следующим образом:

<h3>@Title</h3>
<p>@ChildContent</p>
<br />
<p>Значение: @Count</p>
<button @onclick="IncrementCounter" @attributes="Parameters">Прибавить 1</button>
<button @onclick="DecrementCounter" @attributes="Parameters">Отнять 1</button>

@code {
    private static Dictionary<string, object> buttonParams = new Dictionary<string, object>()
    {
       {"type", "button" },
       {"class", "btn btn-primary" }
    };

    [Parameter, EditorRequired]
    public string Title { get; set; }

    [Parameter]
    public int Count { get; set; }

    [Parameter]
    public RenderFragment? ChildContent { get; set; }


    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object> Parameters { get; set; } = buttonParams;

    private void IncrementCounter()
    {
        Count++;  
    }

    private void DecrementCounter()
    {
        Count--;
    }
}

здесь мы объявили новый параметр:

[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object> Parameters { get; set; } = buttonParams;

Свойство CaptureUnmatchedValues  атрибута [Parameter] указывает на то, что свойство Parameters будет соответствовать всем остальным атрибутам, которые не соответствуют параметрам данного компонента. По умолчанию свойству Parameters назначен словарь, созданный нами выше, то есть внешний вид компонента никак не поменяется. Теперь перейдем в Home.razor и перепишем его следующим образом:

<SmartCounter Title="Smart-счётчик" Count="10" Parameters="buttonParams">
    Этот счётчик с параметрами, переданными из родительского компонента
</SmartCounter>
<hr />

<SmartCounter Title="Smart-счётчик" Count="10" @attributes="buttonParams2">
    Этот счётчик тоже с параметрами, переданными из родительского компонента
</SmartCounter>

<hr />
<SmartCounter Title="Smart-счётчик" Count="10">
    А это счётчик с параметрами по умолчанию
</SmartCounter>
@code{
    Dictionary<string, object> buttonParams = new Dictionary<string, object>()
    {
       {"type", "button" }, 
       {"class", "btn btn-danger" }
    };

    Dictionary<string, object> buttonParams2 = new Dictionary<string, object>()
    {
       {"type", "button" },
       {"class", "btn btn-success" }
    };
}

Здесь мы объявили два словаря с различными значениями атрибутов:

Dictionary<string, object> buttonParams = new Dictionary<string, object>()
{
   {"type", "button" }, 
   {"class", "btn btn-danger" }
};

Dictionary<string, object> buttonParams2 = new Dictionary<string, object>()
{
   {"type", "button" },
   {"class", "btn btn-success" }
};

и добавили на страницу три компонента счётчиков. Первый компонент принимает набор параметров через свой параметр Parameters:

<SmartCounter Title="Smart-счётчик" Count="10" Parameters="buttonParams">
    Этот счётчик с параметрами, переданными из родительского компонента
</SmartCounter>

Здесь мы используем обычную передачу параметров из родительского компонента в дочерний, как мы это делали в предыдущей части.

Второй счётчик использует директиву @attributes и, благодаря свойству CaptureUnmatchedValues атрибута [Parameter] параметр счётчика получит передаваемые в директиве значения

<SmartCounter Title="Smart-счётчик" Count="10" @attributes="buttonParams2">
    Этот счётчик тоже с параметрами, переданными из родительского компонента
</SmartCounter>

Третий счётчик использует свойство Parameters со значениями по умолчанию:

<SmartCounter Title="Smart-счётчик" Count="10">
    А это счётчик с параметрами по умолчанию
</SmartCounter>

Запустим приложение и посмотрим на результат:

Итого

При необходимости, мы можем передавать в компоненты Razor наборы произвольных параметров через директиву @attributes.  Набор произвольных параметр должен передаваться в виде словаря объекта, реализующего интерфейс IDictionary<string, object>, например, как обычный словарь Dictionary<string, object>.

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