Привязка данных и обработка событий
Применяйте одностороннюю и двустороннюю привязку данных, обрабатывайте события DOM и компонентов и используйте EventCallback.
«Привязка данных и обработка событий» — бесплатный урок C# Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Привязка в Blazor
Blazor поддерживает три направления привязки: одностороннюю (только чтение, @expr), событийную (@onclick и другие) и двустороннюю (@bind). Вместе они образуют основу реактивных пользовательских интерфейсов.
Односторонняя привязка данных
Просто выведите выражение C# внутри разметки с помощью @. Значение обновляется при каждом повторном отображении компонента, но DOM не может передать значения обратно в C#.
<!-- One-way: C# -> DOM -->
<p>Count: @_count</p>
<p>Full name: @($"{_firstName} {_lastName}")</p>
<p>Price: @Price.ToString("C")</p>
@code {
private int _count = 0;
private string _firstName = "Alice";
private string _lastName = "Smith";
[Parameter] public decimal Price { get; set; }
}Двусторонняя привязка с помощью @bind
@bind связывает элемент ввода с полем, используя установку свойства и события изменения. Она работает с текстом, числами, датами, флажками и списками выбора.
<input @bind="_name" placeholder="Enter name" />
<input type="number" @bind="_quantity" />
<input type="date" @bind="_dueDate" />
<input type="checkbox" @bind="_isActive" />
<p>Name: @_name | Qty: @_quantity | Active: @_isActive</p>
@code {
private string _name = "";
private int _quantity = 1;
private DateTime _dueDate = DateTime.Today;
private bool _isActive = true;
}@bind с пользовательским событием
По умолчанию @bind использует событие onchange. Используйте @bind:event, чтобы изменить его — например, oninput срабатывает после каждого нажатия клавиши, что удобно для поиска в реальном времени.
@* Updates on every keystroke instead of on focus-loss *@
<input @bind="_search"
@bind:event="oninput"
placeholder="Live search..." />
<ul>
@foreach (var item in Filtered)
{
<li>@item</li>
}
</ul>
@code {
private string _search = "";
private string[] Items = { "Apple", "Banana", "Cherry", "Avocado" };
private IEnumerable<string> Filtered =>
Items.Where(i => i.Contains(_search, StringComparison.OrdinalIgnoreCase));
}Обработка событий с помощью @onclick
Используйте @onclick и другие директивы событий DOM, чтобы привязывать делегаты C# к событиям DOM. Работают как синхронные методы, так и асинхронные задачи.
<button @onclick="Increment">+</button>
<button @onclick="DecrementAsync">-</button>
<button @onclick="() => _count = 0">Reset</button>
<p>Count: @_count</p>
@code {
private int _count = 0;
private void Increment() => _count++;
private async Task DecrementAsync()
{
await Task.Delay(200); // simulate async work
_count--;
}
}Аргументы событий
События DOM предоставляют объекты аргументов событий. Укажите в обработчике подходящий тип аргументов, чтобы получить доступ к координатам, кодам клавиш, значениям ввода и другим данным.
<input @onkeydown="OnKeyDown" @onfocus="OnFocus" />
<div @onmousemove="OnMouseMove">Move here</div>
<p>@_info</p>
@code {
private string _info = "";
private void OnKeyDown(KeyboardEventArgs e)
=> _info = $"Key: {e.Key} (Ctrl={e.CtrlKey})";
private void OnFocus(FocusEventArgs e)
=> _info = "Input focused";
private void OnMouseMove(MouseEventArgs e)
=> _info = $"Mouse: ({e.ClientX}, {e.ClientY})";
}EventCallback для взаимодействия родительского и дочернего компонентов
EventCallback — это стандартный способ взаимодействия дочернего компонента с родительским в Blazor. В отличие от обычного делегата, он автоматически вызывает StateHasChanged у родительского компонента и корректно обрабатывает исключения.
@* Child: ProductCard.razor *@
<button @onclick="() => OnBuy.InvokeAsync(Product)">Buy</button>
@code {
[Parameter] public Product Product { get; set; } = default!;
[Parameter] public EventCallback<Product> OnBuy { get; set; }
}
@* Parent: *@
<ProductCard Product="p" OnBuy="HandleBuy" />
@code {
private async Task HandleBuy(Product p)
{
await CartService.AddAsync(p);
// Parent re-renders automatically
}
}Предотвращение стандартного действия и остановка распространения
Используйте @onclick:preventDefault, чтобы отменить стандартное действие браузера, и @onclick:stopPropagation, чтобы остановить всплытие события.
@* Prevent form submission *@
<form @onsubmit="HandleSubmit" @onsubmit:preventDefault>
<input @bind="_value" />
<button type="submit">Save</button>
</form>
@* Stop click from bubbling to parent div *@
<div @onclick="ParentClicked">
<button @onclick="ChildClicked"
@onclick:stopPropagation>
Click me
</button>
</div>Двусторонняя привязка с помощью @bind-Value в пользовательских компонентах
Реализуйте шаблон Value/ValueChanged в пользовательском компоненте, чтобы поддержать привязку @bind-Value из родительского компонента — это стандартный контракт двусторонней привязки Blazor.
@* RatingInput.razor *@
@for (int i = 1; i <= 5; i++)
{
int star = i;
<span class="@(star <= Value ? "filled" : "")"
@onclick="() => ValueChanged.InvokeAsync(star)">★</span>
}
@code {
[Parameter] public int Value { get; set; }
[Parameter] public EventCallback<int> ValueChanged { get; set; }
}
@* Usage: *@
<RatingInput @bind-Value="_rating" />Задержка обработки событий ввода
Для ресурсоёмких операций, запускаемых вводом пользователя, таких как вызовы API и сложная фильтрация, откладывайте обработку события с помощью CancellationTokenSource, чтобы начать выполнение после того, как пользователь перестанет печатать.
@code {
private string _query = "";
private CancellationTokenSource? _cts;
private async Task OnSearchInput(ChangeEventArgs e)
{
_query = e.Value?.ToString() ?? "";
_cts?.Cancel();
_cts = new CancellationTokenSource();
try
{
await Task.Delay(300, _cts.Token); // wait 300ms
Results = await SearchService.SearchAsync(_query);
}
catch (TaskCanceledException) { /* user still typing */ }
}
private List<string> Results = new();
}Быстрая проверка
В чём преимущество EventCallback перед обычным делегатом для передачи событий от дочернего компонента родительскому в Blazor?
Итоги: привязка данных и обработка событий
Главные выводы:
- Односторонняя привязка: выводите выражения C# с помощью
@expr - Двусторонняя привязка: используйте
@bindдля элементов ввода;@bind:eventизменяет событие-триггер - События DOM:
@onclick,@oninput,@onkeydownс типизированными аргументами событий EventCallback<T>: взаимодействие дочернего компонента с родительским с автоматическим вызовом StateHasChanged- Реализуйте Value/ValueChanged для двусторонней привязки пользовательского компонента
- Откладывайте ресурсоёмкие операции, чтобы сократить количество ненужных вызовов API
Часто задаваемые вопросы
Урок «Привязка данных и обработка событий» бесплатный?
Да — полный текст урока «Привязка данных и обработка событий» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Привязка данных и обработка событий»?
Применяйте одностороннюю и двустороннюю привязку данных, обрабатывайте события DOM и компонентов и используйте EventCallback. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Привязка данных и обработка событий»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Модель компонентов Blazor
- Привязка данных и обработка событий
- Взаимодействие компонентов и DI
- Управление состоянием в Blazor