Обработка событий вложенного компонента в родительском

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

Родительский компонент может устанавливать обработчик события на вложенном компоненте. Для этого применяется тип EventCallback. Он имеет две формы:

  • EventCallback

  • EventCallback<T>

Если применяется форма EventCallback<T>, то обработчик события в качестве параметра принимает значение типа T.

Возьмем вначале нетипизированную форму EventCallback. Допустим, у нас в проекте; который использует интерактивный рендеринг сервера, есть главный компонент App.razor, есть родительский компонент Home.razor и дочерний компонент Counter.razor:

Обработка событий с помощью EventCallback в Blazor

Пусть корневой компонент App.razor просто загружает компонент Home.razor:

@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>

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

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

<div>
    <button @onclick="OnClickCallback">Click</button>
</div>

@code {
    [Parameter]
    public EventCallback OnClickCallback { get; set; }
}

Свойство-параметр EventCallback OnClickCallback представляет обработчик события нажатия кнопки, который не принимает параметров.

Теперь вызовем этот компонент из родительского компонента Home.razor:

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

<h1>Blazor Counter</h1>
<div>@count</div>
<Counter OnClickCallback="@Increment" />

@code {

    int count;
    void Increment() => count++;
}

Здесь в компонент Home параметру OnClickCallback передается метод Increment, который не имеет параметров и будет выполнять функцию обработчика события нажатия кнопки в компоненте Home. Таким образом, нажатие кнопки в компоненте Home будет вызывать метод Increment, который увеличит счетчик в компоненте App.

Обработка событий родительских компонентов в дочерних в Blazor и C#

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

Подобным образом можно устанавливать несколько обработчиков. Например, определим в компоненте Counter две кнопки и два разных свойства EventCallback:

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

<div>
    <button @onclick="OnIncreaseCallback">+</button>
    <button @onclick="OnDecreaseCallback">-</button>
</div>

@code {
    [Parameter]
    public EventCallback OnIncreaseCallback { get; set; }
    [Parameter]
    public EventCallback OnDecreaseCallback { get; set; }
}

В компоненте Home определим для них обработчики:

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

<h2>Count: @count</h2>
<Counter OnIncreaseCallback="Increase" OnDecreaseCallback="Decrease" />
@code {
    int count;
    void Increase() => count++;
    void Decrease() => count--;
}
Установка обобработчиков событий EventCallback для вложенных компонентов Blazor в C#

EventCallback<T>

Ряд событий позволяют передавать в обработчик аргумент определенного типа, например, при событии нажатия кнопки мыши, в обработчик передается аргумент типа MouseEventArgs. Если мы хотим получить этот объект, то нам надо типизировать его типом EventCallback.

Например, мы хотим получить в родительском компоненте координаты нажатия в дочернем компоненте. Для этого изменим компонент Counter следующим образом:

@using Microsoft.AspNetCore.Components.Web

<div style="width:100px;height:100px;background-color:#ccc;" @onclick="OnClickCallback"></div>

@code {
    [Parameter]
    public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}

Тип EventCallback<MouseEventArgs> указывает, что в обработчике события с помощью параметра типа MouseEventArgs мы можем получить информацию о нажатии кнопки мыши.

Теперь изменим родительский компонент Home.razor:

icrosoft.AspNetCore.Components.Web
@rendermode RenderMode.InteractiveServer

<h1>Blazor Counter</h1>
<div>@coords</div>
<Counter OnClickCallback="@GetCoords" />

@code {

    string coords = "";

    void GetCoords(MouseEventArgs e)
    {
        coords = $"Coords X = {e.ClientX}  Y= {e.ClientY}";
    }
}

В данном случае мы просто получаем координаты нажатия кнопки мыши:

EventCallback<T> и обработка событий в приложении Blazor на C#

Передача произвольного объекта в обработчик события

Выше мы рассмотрели, как в обработчике события мы можем получить аргумент события (на примере MouseEventArgs). Но в реальности мы можем передавать в обработчик события объект любого типа. Рассмотрим, более сложную композицию. Например, главный компонент выводит список объектов, а дочерний компонент может добавлять в этот список новые объекты.

Пусть компонент Counter выглядит следующим образом:

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

<div>
    <input type="text" @bind-value="@item" />
    <button @onclick="@(async() => await OnClickCallback.InvokeAsync(item))">Add</button>
</div>

@code {

    string item = "";

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

Итак, в компоненте есть переменная item - некоторая строка, которая с помощью атрибута @bind-value="@item" привязана к текстовому полю input. То есть введенное в это поле значение и будет значением переменной item.

И есть кнопка, по нажатию которой вызывается обработчик OnClickCallback. Он типизирован типом string - EventCallback<string> OnClickCallback. А это значит, что в обработчике события можно с помощью параметра типа string получить переданную в него строку. Обработите внимание, как он вызывается:

await OnClickCallback.InvokeAsync(item)

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

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

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

<div>
    <input type="text" @bind-value="@item" />
    <button @onclick="@OnClick">Add Item</button>
</div>

@code {

    string item = "";

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

    async Task OnClick()
    {
        await OnClickCallback.InvokeAsync(item);
    }
}

Теперь изменим компонент Home:

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

<h2>Users</h2>

<Counter OnClickCallback="@AddNewUser" />
<ul>
    @foreach (var user in users)
    {
        <li>@user</li>
    }
</ul>
@code {

    List<string> users = [];

    void AddNewUser(string user)
    {
        users.Add(user);
    }
}

В компоненте App есть список строк - users, который выводится на веб-страницу. По умолчанию он пуст. И с помощью дочернего компонента Home мы будем добавлять в него новые объекты.

Метод AddNewUser передается в компонент Home свойству OnClickCallback. Через его параметр string user мы и сможем получить переданное из компонента Home введенное значение (OnClickCallback.InvokeAsync(item)) и затем добавить это значение в список.

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