Достаточно распространенным сценарием работы в 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>
. В обработчик события в родительском компоненте также можно передавать произвольные объекты, используя лямбда-выражения.