Достаточно распространенным сценарием работы в Blazor с вложенными (дочерними) компонентами является выполнение метода родительского компонента при возникновении события у дочернего компонента. Например, когда в дочернем элементе возникает событие onclick необходимо вызывать какой-либо метод, определенный в родительском компоненте.
EventCallback
Родительский компонент может назначить метод обратного вызова типа EventCallback дочернего компонента. Рассмотрим пример использования типа EventCallback в шаблонном приложении Blazor Server. Редактировать будем код компонента SurveyPrompt.razor. Этот компонент является дочерним для компонента Index.razor и вполне подходит для примера. Алгоритм действий будет следующим:
1. Добавим у дочернего компонента (SurveyPrompt) новое свойство-параметр:
[Parameter]
public EventCallback LinkClickCallback { get; set; }
2. Установим это свойство в качестве обработчика события click ссылки в компоненте:
....
<span class="text-nowrap">
Please take our
<a target="_blank" class="font-weight-bold link-dark" href="https://go.microsoft.com/fwlink/?linkid=2149017" @onclick="LinkClickCallback">brief survey</a>
</span>
and tell us what you think.
.....
3. У родительского компонента (Index) напишем метод обработки события и назначим этот метод в качестве обработчика события дочернего компонента:
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" LinkClickCallback="ClickCallback" />
<p>@message</p>
@code
{
private string? message;
private void ClickCallback()
{
message = "Пользователь нажал на ссылку";
}
}
Теперь можно запустить приложение и увидеть, что как только мы кликнем по ссылке и перейдем на страницу опроса по Blazor, то под компонентом SurveyPrompt появится новая строка «Пользователь нажал на ссылку»
EventCallback<T>
Как мы уже знаем, ряд событий в Blazor могут передавать какие-либо аргументы в обработчики. Например, мы рассматривали аргумент типа MouseEventArgs, которые передается при клике мышкой по компоненту. Если нам необходимо передать значения этого аргумента в родительский компонент, то можно воспользоваться типизированной формой EventCallback. Вернемся к нашему компоненту SurveyPrompt и перепишем его код следующим образом:
<div class="alert alert-secondary mt-4" @onclick="ComponentClickCallback">
<span class="oi oi-pencil me-2" aria-hidden="true"></span>
<strong>@Title</strong>
<span class="text-nowrap">
Please take our
<a target="_blank" class="font-weight-bold link-dark" href="https://go.microsoft.com/fwlink/?linkid=2149017" @onclick="LinkClickCallback">brief survey</a>
</span>
and tell us what you think.
</div>
@code {
// Demonstrates how a parent component can supply parameters
[Parameter]
public string? Title { get; set; }
[Parameter]
public EventCallback LinkClickCallback { get; set; }
[Parameter]
public EventCallback<MouseEventArgs> ComponentClickCallback { get; set; }
}
Здесь мы добавили новое свойство-параметр EventCallback<MouseEventArgs> ComponentClickCallbackи указали его в качестве обработчика события click у элемента div.
Теперь допишем компонент Index.razor следующим образом:
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" LinkClickCallback="ClickCallback" ComponentClickCallback="ComponentClicked" />
<p>@message</p>
<p>@coords</p>
@code
{
private string? message;
private string? coords;
private void ClickCallback()
{
message = "Пользователь нажал на ссылку";
}
private void ComponentClicked(MouseEventArgs args)
{
coords = $"X = {args.ClientX} Y = {args.ClientY}";
}
}
Метод ComponentClicked принимает в качестве параметра агрумент события MouseEventArgs и выводит координаты курсора мыши в момент клика. Теперь наш родительский компонент обрабатывает два события click у дочернего компонента и, при этом, во втором случае принимает значение аргумента MouseEventArgs :
Передача произвольного объекта
Как и в случае с обработкой событий, которую мы рассматривали в прошлой теме, мы можем передавать в родительский компонент произвольные объекты, используя лямбда выражения вида:
@onclick="@(()=>[параметр типа EventCallback].InvokeAsync(параметры метода))">
Например, чтобы передать в родительский компонент строку, мы могли бы написать следующий обработчик click:
<div class="alert alert-secondary mt-4" @onclick="@(e=>ComponentClickCallback.InvokeAsync(data))">
....
</div>
@code {
string data = "click";
.....
[Parameter]
public EventCallback<string> ComponentClickCallback { get; set; }
}
а в родительском компоненте метод обработки события можно было бы сделать таким:
.....
<SurveyPrompt Title="How is Blazor working for you?" LinkClickCallback="ClickCallback" ComponentClickCallback="ComponentClicked" />
.....
<ul>
@foreach (var coord in coords)
{
<li>@coord</li>
}
</ul>
@code
{
....
private List<string> coords = new List<string>();
....
private void ComponentClicked(string coord)
{
coords.Add(coord);
}
}
В этом случае, в запущенном приложении мы бы увидели следующее:
Итого
Для того, чтобы родительский компонент мог обрабатывать события дочернего компонента, дочерний компонент должен объявить публичное свойство-параметр типа EventCallback или его типизированный вариант — EventCallback<T>. В обработчик события в родительском компоненте также можно передавать произвольные объекты, используя лямбда-выражения.


