Каскадные значения и параметры

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

Объект для каскадного параметра

Прежде, чем приступим к рассмотрению темы, необходимо определиться с тем, что мы будем передавать по иерархии компонентов. Допустим, мы хотим, чтобы наше приложение меняло тему оформления в зависимости от каких-либо настроек. Для примера создадим следующий класс:

namespace BlazorCascade
{
    public class Theme
    {
        public string ButtonClass { get; set; } = "btn btn-primary";
        public string AlertClass { get; set; } = "alert alert-primary";
        public string TableStyle { get; set; } = "table table-dark table-striped";
    }
}

здесь класс Theme содержит свойства, каждое из которых отвечает за класс определенного html-элемента. Эти классы используются фреймворком Bootstrap, который по умолчанию включен в проект.

Объекты этого класса и будут выступать в качестве каскадного значения в нашем проекте.

Каскадные значения корневого уровня

Каскадные значения регистрируются в контейнере зависимостей непосредственно в файле MauiProgram.cs. Для этого используется специальный метод расширения AddCascadingValue(), который имеет несколько перегруженных версий. Откроем файл MauiProgram.cs и зарегистрируем несколько тем оформления:

    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });

            builder.Services.AddCascadingValue(theme => new Theme()); //регистрируем тему оформления со значениями по умолчанию
           
            builder.Services.AddCascadingValue("DangerTheme", theme => new Theme() 
            { 
                ButtonClass = "btn btn-danger",
                AlertClass = "alert alert-danger",
                TableStyle = "table table-light table-striped"
            }); //регистрируем тему оформления со определенными значениями

            builder.Services.AddMauiBlazorWebView();

#if DEBUG
    		builder.Services.AddBlazorWebViewDeveloperTools();
    		builder.Logging.AddDebug();
#endif

            return builder.Build();
        }
    }

Здесь мы добавили два объекта Theme. Первый объект содержит значения свойств по умолчанию:

builder.Services.AddCascadingValue(theme => new Theme());

Второй объект содержит уже определенные нами значения и регистрируется с использованием второй версии метода в которой мы указываем имя для каскадного значения:

builder.Services.AddCascadingValue("DangerTheme", theme => new Theme() 
{ 
    ButtonClass = "btn btn-danger",
    AlertClass = "alert alert-danger",
    TableStyle = "table table-light table-striped"
});

Теперь изменим код файла Home.razor следующим образом

@page "/"

<h1>Hello, world!</h1>

<div class="@Theme?.AlertClass" role="alert">
    Hello, world!
</div>

<button class="@Theme?.ButtonClass">My Button</button>

<hr />

<div class="@OtherTheme?.AlertClass" role="alert">
    Hello, world!
</div>

<button class="@OtherTheme?.ButtonClass">My Button</button>

@code{
    [CascadingParameter]
    public Theme? Theme { get; set; }

    [CascadingParameter(Name = "DangerTheme")]
    public Theme? OtherTheme { get; set; }
}

Для того, чтобы определить в компоненте каскадный параметр применяется атрибут [CascadingParameter]. При этом, мы можем указать для этого атрибута свойство Name — в этом случае значение каскадного параметра будет определять по имени каскадного значения. Например, здесь

[CascadingParameter(Name = "DangerTheme")] 
public Theme? OtherTheme { get; set; }

значение для OtherTheme будет присвоено только в том случае, если найдется каскадное значение с именем «DangerTheme».

В разметке компонента мы применяем различные темы оформления к парам html-элементов. Теперь, если запустить приложение, мы увидим следующий результат:

Компонент <CascadingValue>

Совсем не обязательно, чтобы каскадное значение «разлеталось» сразу по всей иерархии компонентов Razor. Вполне возможно, что вам будет достаточно, чтобы каскадное значение использовалось в какой-то заданной части иерархии компонентов. Для таких целей мы можем воспользоваться специальным компонентом Razor — <CascadingValue>. Например, изменим главный макет нашего приложения (файл MainLayout.razor) следующим образом:

@inherits LayoutComponentBase

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

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

        <article class="content px-4">
            <CascadingValue TValue="Theme" Value="SuccessTheme">
                @Body
            </CascadingValue>
            
        </article>
    </main>
</div>

@code{
    Theme SuccessTheme = new Theme()
        {
            ButtonClass = "btn btn-success",
            AlertClass = "alert alert-success",
            TableStyle = "table table-light table-striped"
        };
}

Здесь содержимое, в котором должны использоваться каскадные параметры расположено внутри компонента <CascadingValue>. Как мы уже знаем, что вместо @Body в приложении выводятся страницы приложения. Таким образом, все страницы приложения и все компоненты на этих страницах будут принимать новый каскадный параметр. При этом, у нас в MauiProgram.cs также определено каскадное значение без имени. Какое из двух значений будет использовано? Ответ — последнее. То есть, корневое  каскадное значение будет перезаписано и в запущенном приложении мы увидим:

Как и в случае с корневыми каскадными значениями, мы можем задать в <CascadingValue> имя каскадного значения. Например:

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

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

        <article class="content px-4">
            <CascadingValue TValue="Theme" Value="SuccessTheme" Name="DangerTheme">
                @Body
            </CascadingValue>
            
        </article>
    </main>
</div>

Теперь мы увидим, что нижняя пара компонентов будет зеленого цвета, то есть каскадное значение применится к свойству OtherTheme компонента Home:

Используя <CascadingValue> мы можем передавать несколько каскадных значений. Например:

<CascadingValue TValue="int" Value="100" Name="Number">
    <CascadingValue TValue="Theme" Value="SuccessTheme" Name="DangerTheme">
        @Body
    </CascadingValue>
</CascadingValue>

В этом случае по иерархии компонентов будут передаваться и объект типа Theme и целое число.

Итого

Каскадные значения могут передаваться по всей или части иерархии компонентов Razor. Для передачи каскадного значения по всей иерархии используется метод расширения IServiceCollection AddCascadingValue(). Для передачи каскадного значения по части иерархии компонентов можно воспользоваться компонентом <CascadingValue>.

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