Каскадные параметры в Blazor

Еще одной полезной возможностью Blazor является то, что компонент-предок может предоставить каскадный параметр с помощью компонента CascadingValue, который заключает поддерево иерархии компонентов и предоставляет одно значение для всех компонентов в его поддереве.

Использование компонента CascadingValue

Одним из возможных вариантов использования компонента CascadingValue является кастомизация темы оформления вашего приложения. Например, рассмотрим стандартный шаблон приложения Blazor Server в состав которого входит компонент счётчика, таблица с данным о метеоусловиях и компонент опроса. Для изменения стиля отрисовки каждого элемента мы могли бы задавать каждый стиль по-отдельности вручную, а можем воспользоваться каскадным параметром с использованием CascadingValue. Чтобы продемонстрировать как работает этот компонент выполним следующие действия:

 1. Создадим новый класс ThemeTemplate со следующими свойствами:

namespace BlazorApp1
{
    public class ThemeTemplate
    {
        public string ButtonStyle { get; set; }
        public string TableStyle { get; set; }
    }
}

Этот класс будет содержать CSS-стили кнопок и таблиц нашего приложения.

2. В макете приложения (файл MainLayout.razor) используем CascadingValue

@inherits LayoutComponentBase

<PageTitle>BlazorApp1</PageTitle>

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
        </div>

        <CascadingValue Value="template">
        <article class="content px-4">
            @Body
        </article>
        </CascadingValue>

    </main>
</div>

@code 
{
    ThemeTemplate template = new ThemeTemplate()
        {
            ButtonStyle = "btn-danger",
            TableStyle = "table table-dark table-striped"
        };
}

3. Чтобы дочерние компоненты могли воспользоваться каскадным параметром, компоненты-потомки объявляют каскадные параметры с помощью атрибута [CascadingParameter]. Каскадные значения привязаны к каскадным параметрам по типу. Объявим такие параметры на страницах Counter.razor и FetchData.razor

Страница Counter.razor:

@page "/counter"

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn @Template.ButtonStyle" @onclick="IncrementCount">Click me</button>

@code {

    [CascadingParameter]
    public ThemeTemplate Template { get; set; }

    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

Страница FetchData.razor:

@page "/fetchdata"

<PageTitle>Weather forecast</PageTitle>

@using BlazorApp1.Data
@inject WeatherForecastService ForecastService

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from a service.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="@Template.TableStyle">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {

    [CascadingParameter]
    public ThemeTemplate Template { get; set; }

    private WeatherForecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
    }
}

Теперь можем запустить приложение и посмотреть как изменится стиль кнопки и таблицы:

Каскадный параметр для кнопки
Каскадный параметр для кнопки

Таблица с каскадным параметром:

Каскадный параметр для таблицы
Каскадный параметр для таблицы

Каскадное применение нескольких значений

Чтобы выполнить каскадное применение нескольких значений одного типа в одном поддереве, необходимо указать уникальную строку Name для каждого компонента CascadingValue и его соответствующих атрибутов [CascadingParameter]. Например добавим ещё одну тему оформления:

Файл MainLayout.razor

@inherits LayoutComponentBase

<PageTitle>BlazorApp1</PageTitle>

<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
        </div>

        <CascadingValue Value="template" Name="MainTheme">
            <CascadingValue Value="otherTemplate" Name="SecondTheme">
                <article class="content px-4">
                    @Body
                </article>
            </CascadingValue>
        </CascadingValue>

    </main>
</div>

@code
{
    ThemeTemplate template = new ThemeTemplate()
        {
            ButtonStyle = "btn-danger",
            TableStyle = "table table-dark table-striped"
        };

    ThemeTemplate otherTemplate = new ThemeTemplate()
        {
            ButtonStyle = "btn-success",
            TableStyle = "table table-dark table-striped"
        };

}

Файл Counter.razor— применим вторую тему оформления

///Код компонента/////
<button class="btn @Template.ButtonStyle" @onclick="IncrementCount">Click me</button>

@code {
    @*Применяем вторую тему оформления*@
    [CascadingParameter(Name ="SecondTheme")]
    public ThemeTemplate Template { get; set; }
    
    ///Код компонента/////
}

Файл FetchData.razor— оставим тему оформления из предыдущего примера

///Код компонента/////
    <table class="@Template.TableStyle">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {

    [CascadingParameter(Name ="MainTheme")]
    public ThemeTemplate Template { get; set; }
    
///Код компонента/////
}

Результат применения новой темы для кнопки:

Итого

Каскадные параметры в Blazor можно задать с использованием компонента CascadingValue.  Каскадный параметр может использовать любой компонент в дереве иерархии компонента-родителя. Для использования нескольких каскадных параметров, имеющих один и тот же тип значений у компонента CascadingValue необходимо определять уникальный параметр Name.

 

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