Привязка данных

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

Blazor позволяют выполнять привязку значения полей и свойств компонентов к атрибутам элементов HTML. Для этого у элементов HTML применяется атрибут @bind-

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

Например, пусть у нас в проекте есть два компонента: корневой компонент 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>

@bind-атрибут

Привязку данных можно выполнить к любому атрибуту элемента html. Например, у элемента ввода input есть атрибут value, который представляет введенное в элемент значение. Для привязки к этому атрибуту значения применяется атрибут @bind-value (то есть @bind-[название_атрибута]).

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

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

<div>
    <input @bind-value="@item" />
    <p>Value: @item</p>
</div>

@code {

    string item = "hello";
}

Здесь текстовое поле input посредством атрибута @bind-value привязано к значению переменной item. При рендеринге компонента элемент input получает значение переменной item. После того, как пользователь введет в это текстовое поле новое значение и переместит фокус на другой элемент веб-страницы, сработает событие onchange, и значение переменной item будет обновлено.

То есть фактически данный код будет эквивалентен следующему:

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

<div>
    <input value="@item" @onchange="@((ChangeEventArgs e) => item = e.Value.ToString())" />
    <p>Value: @item</p>
</div>

@code {

    string item = "hello";
}

То есть в обработчике события onchange меняется переменной item присваивается новое введенное значение. Однако благодаря атрибуту @bind нам не надо прописывать дополнительно всю эту логику, blazor делает за нас все сам.

Для проверки значение item дополнительно выводится в параграф под текстовым полем:

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

Атрибут @bind

Для элементов ввода input вместо атрибута @bind-value можно использовать его сокращенную версию - @bind:

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

<div>
    <input type="text" @bind="@item" />
    <p>Value: @item</p>
</div>

@code {

    string item = "hello";
}

@bind-атрибут:event

С помощью атрибута @bind-атрибут:event у элементов HTML можно назначить другое событие, которое будет изменять привязанное к элементу значение. По умолчанию за это отвечает событие onchange, которое срабатывает, когда элемент ввода теряет фокус. Так, в примере выше, чтобы после ввода нового значения в текстовое поле изменилось значение переменной item, необходимо было убирать фокус с элемента ввода. Это может быть неудобно. Допустим, мы хотим сразу изменять значение. Для этого используем для обработки изменения значения событие oninput:

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

<div>
    <input @bind-value="@item" @bind-value:event="oninput" />
    <p>Value: @item</p>
</div>

@code {

    string item = "hello";
}

Событие oninput срабатывает сразу, как происходит изменение значения в текстовом поле. То есть теперь не потребуется убирать фокус.

Опять же если привязка идет к атрибуту value, то вместо @bind-value:event можно использовать @bind:event:

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

<div>
    <input @bind="@item" @bind:event="oninput" />
    <p>Value: @item</p>
</div>

@code {

    string item = "hello";
}

Привязка других атрибутов

Выше рассматривалась привязка на примере атрибута value полей input. Но подобным образом можно выполнять привязку и к другим атрибутам. Они работают по тому принципу. Например, выполним привязку к атрибуту style элемента div:

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

<p>
	<input @bind-value="divStyle" @bind-value:event="oninput" style="width:300px;" />
</p>
<div style="@divStyle"></div>

@code {
    string divStyle = "background-color:blue;width:100px;height:100px;";
}

В данном случае идет привязка атрибута style к переменной divStyle, значение которой изменяется в поле ввода

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

onchange vs oninput

Выше в первом примере при вводе значения в текстовое поле при использовании события onchange необходимо было убирать фокус с поля, чтобы привязанное значение изменилось. В то же время при использовании события oninput убирать фокус с элемента не надо, при нажатии клавиши клавиатуры тут же будет изменяться привязанное значение. Вследствие этого может показаться, что лучше использовать событии oninput. Однако в реальности oninput может отрицателным образом сказаться на возможности ввода. Например, возьмем следующий компонент:

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

<div>
    <input @bind-value="number" @bind-value:event="oninput" />
    <p>@number</p>
    
</div>

@code {
    double number = 23.8;
}

Здесь к текстовому полю привязана переменная типа double, которая допускает использование точки или запятой (в зависимости от текущей культуры) для разделения целой и дробной части. Если при вводе мы уберем разделитель целой и дробной части (точку/запятую), оставив только целую часть, и впоследствии попытаемся его ввести после цифровых символов, то мы не сможем это сделать. Так как при событии oninput при каждом нажатии клавиши клавиатуры будет изменятся введенное значение. Введенный символ точки/запятой не сможет быть распарсен и поэтому будет отброшен. Мы сможем ввести только все число полностью.

атрибут bind:event в Blazor

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

Постобработка изменения значения

Чтобы выполнить после установки значения некоторую асинхронную обработку, применяется атрибут @bind:after, которому передается выполняемое действие:

@bind:after="действие"

Выполняемое действие должно возвращать объект Action или Task и выполняется после того, как установлено привязанное значение. Рассмотрим небольшой пример:

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

<input @bind="searchText" @bind:after="PerformSearch" />
<ul>
    @foreach(var item in found)
    {
        <li>@item</li>
    }
</ul>

@code {
    // условная база данных
    List<string> items = [];
    // найденные данные
    List<string> found = [];
    // ключ поиска
    string searchText = "";
    async Task PerformSearch()
    {
        // для имитации долгой работы
        await Task.Delay(400);
        found = items.Where(item => item.Contains(searchText)).ToList();
    }
}

Здесь поле ввода привязано к переменной searchText. После изменения ее значения выполняется асинхронный метод PeformSearch. В данном случае мы делаем условный запрос к базе данных, в роли которой выступает список items. И выбираем из него все элементы, которые содержат текст из searchText. Найденные значения помещаются в список found, который выводится на страницу. Для имитации долгой работы используется задержка в 400 миллисекунд.

Асинхронная обработка значения при привязке в компонентах Blazor в C#

Атрибут @bind:after можно применять, когда надо выполнить некоторую постобработку, в частности, выполнение сетевого запроса, обращение к базе данных. Причем эти действия необязательно должны быть асинхронными методами. Например, в примере выше можно было бы определить метод PeformSearch следующим образом:

void PerformSearch()
{
    found = items.Where(item => item.Contains(searchText)).ToList();
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850