Двусторонняя привязка и привязка параметров компонентов

Последнее обновление: 30.11.2023

Двусторонняя привязка

Компоненты Blazor также поддерживают двустороннюю привязку значений и полей ввода. Для этого применяется следующая пара модификаторов:

  • @bind:get - определяет привязанное значение

  • @bind:set - определяет действия, выполняемые при изменении значения. Это должен быть метод, который возвращает Task или void

Модификаторы @bind:get и @bind:set всегда применяются вместе. И поскольку задействуется интерактивность, то приложение должно поддерживать интерактивный рендеринг на сервере или на клиенте. В данном случае используем интерактивный рендеринг на сервере.

Например, пусть у нас в проекте есть два компонента: корневой компонент App.razor и Home.razor:

Привязка в компонентах Blazor ASP.NET Core

На корневом компоненте App.razor загружается вложенный компонент Home:

@page "/"

<!DOCTYPE html>
<html>
<head>
    <title>METANIT.COM</title>
    <meta charset="utf-8" />
</head>
<body>
    <Home />
    <script src="_framework/blazor.web.js"></script>
</body>
</html>

А в компоненте Home.razor определим следующий код:

@using Microsoft.AspNetCore.Components.Web
@rendermode RenderMode.InteractiveServer

<input type="number" @bind:get="age" @bind:set="SetAge" />
<h2>Age: @age</h2>

@code {
    int age = 18;
    void SetAge(int value)
    {
        if (value > 0 && value < 110) age = value;
    }
}

В данном случае поле ввода числа привязано к переменной age, которая представляет некоторый возраст:

@bind:get="age"

Для обработки изменения значения применяется метод SetAge:

@bind:set="SetAge"

Поскольку значение поля с типом number представляет число, то мы можем получить устанавливаемое значение через параметр метода как значение типа int и решить, будем ли мы изменять значение переменной age:

void SetAge(int value)
{
    if (value > 0 && value < 110) age = value;
}
Отслеживание изменения значения при привязке в компоненте Blazor в C#

При этом если мы НЕ изменим значение переменной age, то число в текстовом поле обновится на текущее значение age.

В качестве альтернативы модификаторам @bind:get и @bind:set можно использовать геттеры и сеттеры свойств, который также позволяют организавать двустороннюю привязку и отслеживать передаваемое значение:

@using Microsoft.AspNetCore.Components.Web
@rendermode RenderMode.InteractiveServer

<input type="number" @bind="Age" />
<h2>Age: @Age</h2>

@code {
    int age = 18;

    int Age
    {
        get { return age; }
        set
        {
            if (value > 0 && value < 110) age = value;
        }
    }
}

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

Причем для установки двусторонней привязки достаточно установить атрибут @bind:

 @bind="Age"

Привязка параметров вложенных компонентов

Механизм привязки Blazor действует и для параметров вложенных компонентов. Например, пусть у нас в проекте также есть компонент Main.razor, который будет дочерним по отношению к "Home.razor"

Привязка данных к параметрам вложенных компонентов Blazor в C#

Пусть компонент Main определяет свойство-параметр Title:

@using Microsoft.AspNetCore.Components.Web
@rendermode RenderMode.InteractiveServer

<h1>@Title</h1>

@code {
    [Parameter]
    public string Title { get; set; } = "";
}

В компоненте Home передаем устанавливаем привязку с параметром Title:

@using Microsoft.AspNetCore.Components.Web
@rendermode RenderMode.InteractiveServer

<Main Title="@title" />
<input @bind="@title" />

@code {
    string title = "Hello";
}

Здесь переменная title привязана и к параметру Title компонента Main, и к тексту в поле ввода. И при изменении текста в поле ввода изменится также заголовок в компоненте Main:

Привязка значений родительских и вложенных компонентов Blazor в C#

Двусторонняя привязка параметров

Двусторонняя привязка также может вовлекать параметры вложенных компонентов. Посмотрим, как организовать подобную привязку. Возьмем те же компоненты Home и Main

В компоненте Main определим следующий код:

@using Microsoft.AspNetCore.Components.Web
@rendermode RenderMode.InteractiveServer


<input @onchange="ChangeValue" value="@search" />
@code {
    string? search = "";
    [Parameter]
    public string? Search 
    { 
      get { return search; } 
      set { search = value; } 
    }

    [Parameter]
    public EventCallback<string> SearchChanged { get; set; }

    async Task ChangeValue(ChangeEventArgs e)
    {
        search = e?.Value?.ToString();
        await SearchChanged.InvokeAsync(search);
    }
}

Здесь компонент содержит свойство-параметр Search, которое хранит данные в переменной search. Эта переменная привязана к полю ввода. При изменении значения вызывается метод ChangeValue, в котором переустанавливается значение переменной search (она получает введенное в текстовое поле значение) и вызывается коллбек SearchChanged.

Также определим компонент Home со следующим кодом:

@using Microsoft.AspNetCore.Components.Web
@rendermode RenderMode.InteractiveServer

<Main @bind-Search="text" />
<p><button @onclick="Clear">Clear</button></p>
<ul>
    @foreach(var item in Found)
    {
        <li>@item</li>
    }
</ul>

@code {
    string text = "C";    // искомое слово
    // условная база данных
    List<string> database  = ["C#", "C++", "JavaScript", "Java", "Python"];
    // найденные элементы
    List<string> Found 
    { 
        get { return database.Where(name => name.Contains(text)).ToList(); } 
    }
    // очищаем поиск
    void Clear() => text = "";
}

Компонент Home определяет переменную text, которая будет хранить ключ поиска. Также в компоненте определен список database - условная база данных, в которой будет идти поиск, а также список Found, который будет хранить найденные из database данные и который будет выводиться на страницу в элемент <ul>. Кроме того, метод Clear() позволяет сбросить значение переменной text.

Причем сам ввод строки для переменной text будет идти в компоненте Main:

<Main @bind-Search="text" />

Здесь устанавливается привязка к параметру Search компонента Main - он привязан к переменной text. Для установки привязки к параметру применяется атрибут

@bind-Параметр

То есть при запуске приложения параметр Search из компонента Main получит значение переменной text. Но здесь еще есть один момент - в компоненте Home должен быть определен EventCallback, который должен называться ПараметрChanged. И именно для этого в компоненте Home определено свойство

public EventCallback<string> SearchChanged { get; set; }

Поскольку параметр Search и переменная text представляют тип String, то SearchChanged также типизирован типом string.

В итоге когда в компоненте Main изменится текст в текстовом поле, сработает метод ChangeValue, который в свою очередь вызовет коллбек SearchChanged

async Task ChangeValue(ChangeEventArgs e)
{
    search = e?.Value?.ToString();
    await SearchChanged.InvokeAsync(search);
}

После вызова коллбека SearchChanged компонент Home автоматически получит новое значение и изменит значение переменной text:

EventCallback и двусторонняя привязка данных в компонентах Blazor в C#
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850