Sdílet prostřednictvím


zpracování událostí ASP.NET Core Blazor

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Upozorňující

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Tento článek vysvětluje Blazorfunkce zpracování událostí, včetně typů argumentů událostí, zpětného volání událostí a správy výchozích událostí prohlížeče.

Delegování obslužných rutin událostí

Zadejte obslužné rutiny událostí delegáta v Razor kódu komponenty pomocí @on{DOM EVENT}="{DELEGATE}"Razor syntaxe:

  • Zástupný {DOM EVENT} symbol je událost MODELU DOM (například click).
  • Zástupný {DELEGATE} symbol je obslužná rutina události delegáta jazyka C#.

Zpracování událostí:

  • Obslužné rutiny událostí delegáta jsou Blazor Web Appvolána pouze v komponentách, které přijímají interaktivní režim vykreslování. V příkladech v tomto článku se předpokládá, že aplikace přijímá interaktivní režim vykreslování globálně v kořenové komponentě aplikace, obvykle komponentu App . Další informace najdete v tématu ASP.NET režimy vykreslování coreBlazor.
  • Asynchronní delegování obslužných rutin událostí, které vrací Task , jsou podporovány.
  • Obslužné rutiny událostí delegování automaticky aktivují vykreslení uživatelského rozhraní, takže není nutné ručně volat StateHasChanged.
  • Zaprotokolují se výjimky.
  • Asynchronní delegování obslužných rutin událostí, které vrací Task , jsou podporovány.
  • Obslužné rutiny událostí delegování automaticky aktivují vykreslení uživatelského rozhraní, takže není nutné ručně volat StateHasChanged.
  • Zaprotokolují se výjimky.

Následující kód:

  • Volá metodu UpdateHeading , když je tlačítko vybráno v uživatelském rozhraní.
  • Volá metodu CheckChanged při změně zaškrtávacího políčka v uživatelském rozhraní.

EventHandler1.razor:

@page "/event-handler-1"

<PageTitle>Event Handler 1</PageTitle>

<h1>Event Handler Example 1</h1>

<h2>@headingValue</h2>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

<p>
    <label>
        <input type="checkbox" @onchange="CheckChanged" />
        @checkedMessage
    </label>
</p>

@code {
    private string headingValue = "Initial heading";
    private string checkedMessage = "Not changed yet";

    private void UpdateHeading() => headingValue = $"New heading ({DateTime.Now})";

    private void CheckChanged() => checkedMessage = $"Last change {DateTime.Now}";
}

EventHandlerExample1.razor:

@page "/event-handler-1"

<h1>@headingValue</h1>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

<p>
    <label>
        <input type="checkbox" @onchange="CheckChanged" />
        @checkedMessage
    </label>
</p>

@code {
    private string headingValue = "Initial heading";
    private string checkedMessage = "Not changed yet";

    private void UpdateHeading()
    {
        headingValue = $"New heading ({DateTime.Now})";
    }

    private void CheckChanged()
    {
        checkedMessage = $"Last changed at {DateTime.Now}";
    }
}

EventHandlerExample1.razor:

@page "/event-handler-1"

<h1>@headingValue</h1>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

<p>
    <label>
        <input type="checkbox" @onchange="CheckChanged" />
        @checkedMessage
    </label>
</p>

@code {
    private string headingValue = "Initial heading";
    private string checkedMessage = "Not changed yet";

    private void UpdateHeading()
    {
        headingValue = $"New heading ({DateTime.Now})";
    }

    private void CheckChanged()
    {
        checkedMessage = $"Last changed at {DateTime.Now}";
    }
}

EventHandlerExample1.razor:

@page "/event-handler-1"

<h1>@headingValue</h1>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

<p>
    <label>
        <input type="checkbox" @onchange="CheckChanged" />
        @checkedMessage
    </label>
</p>

@code {
    private string headingValue = "Initial heading";
    private string checkedMessage = "Not changed yet";

    private void UpdateHeading()
    {
        headingValue = $"New heading ({DateTime.Now})";
    }

    private void CheckChanged()
    {
        checkedMessage = $"Last changed at {DateTime.Now}";
    }
}

EventHandlerExample1.razor:

@page "/event-handler-1"

<h1>@headingValue</h1>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

<p>
    <label>
        <input type="checkbox" @onchange="CheckChanged" />
        @checkedMessage
    </label>
</p>

@code {
    private string headingValue = "Initial heading";
    private string checkedMessage = "Not changed yet";

    private void UpdateHeading()
    {
        headingValue = $"New heading ({DateTime.Now})";
    }

    private void CheckChanged()
    {
        checkedMessage = $"Last changed at {DateTime.Now}";
    }
}

V následujícím příkladu: UpdateHeading

  • Je volána asynchronně, když je tlačítko vybráno.
  • Před aktualizací nadpisu počká dva sekundy.

EventHandler2.razor:

@page "/event-handler-2"

<PageTitle>Event Handler 2</PageTitle>

<h1>Event Handler Example 2</h1>

<h2>@headingValue</h2>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

@code {
    private string headingValue = "Initial heading";

    private async Task UpdateHeading()
    {
        await Task.Delay(2000);

        headingValue = $"New heading ({DateTime.Now})";
    }
}

EventHandlerExample2.razor:

@page "/event-handler-2"

<h1>@headingValue</h1>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

@code {
    private string headingValue = "Initial heading";

    private async Task UpdateHeading()
    {
        await Task.Delay(2000);

        headingValue = $"New heading ({DateTime.Now})";
    }
}

EventHandlerExample2.razor:

@page "/event-handler-2"

<h1>@headingValue</h1>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

@code {
    private string headingValue = "Initial heading";

    private async Task UpdateHeading()
    {
        await Task.Delay(2000);

        headingValue = $"New heading ({DateTime.Now})";
    }
}

EventHandlerExample2.razor:

@page "/event-handler-2"

<h1>@headingValue</h1>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

@code {
    private string headingValue = "Initial heading";

    private async Task UpdateHeading()
    {
        await Task.Delay(2000);

        headingValue = $"New heading ({DateTime.Now})";
    }
}

EventHandlerExample2.razor:

@page "/event-handler-2"

<h1>@headingValue</h1>

<p>
    <button @onclick="UpdateHeading">
        Update heading
    </button>
</p>

@code {
    private string headingValue = "Initial heading";

    private async Task UpdateHeading()
    {
        await Task.Delay(2000);

        headingValue = $"New heading ({DateTime.Now})";
    }
}

Předdefinované argumenty událostí

U událostí, které podporují typ argumentu události, je zadání parametru události v definici metody události nezbytné pouze v případě, že je v metodě použit typ události. V následujícím příkladu ReportPointerLocation se v metodě používá k nastavení textu zprávy, který hlásí souřadnice myši, MouseEventArgs když uživatel vybere tlačítko v uživatelském rozhraní.

EventHandler3.razor:

@page "/event-handler-3"

<PageTitle>Event Handler 3</PageTitle>

<h1>Event Handler Example 3</h1>

@for (var i = 0; i < 4; i++)
{
    <p>
        <button @onclick="ReportPointerLocation">
            Where's my mouse pointer for this button?
        </button>
    </p>
}

<p>@mousePointerMessage</p>

@code {
    private string? mousePointerMessage;

    private void ReportPointerLocation(MouseEventArgs e) => 
        mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
}

EventHandlerExample3.razor:

@page "/event-handler-example-3"

@for (var i = 0; i < 4; i++)
{
    <p>
        <button @onclick="ReportPointerLocation">
            Where's my mouse pointer for this button?
        </button>
    </p>
}

<p>@mousePointerMessage</p>

@code {
    private string? mousePointerMessage;

    private void ReportPointerLocation(MouseEventArgs e)
    {
        mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
    }
}

EventHandlerExample3.razor:

@page "/event-handler-example-3"

@for (var i = 0; i < 4; i++)
{
    <p>
        <button @onclick="ReportPointerLocation">
            Where's my mouse pointer for this button?
        </button>
    </p>
}

<p>@mousePointerMessage</p>

@code {
    private string? mousePointerMessage;

    private void ReportPointerLocation(MouseEventArgs e)
    {
        mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
    }
}

EventHandlerExample3.razor:

@page "/event-handler-example-3"

@for (var i = 0; i < 4; i++)
{
    <p>
        <button @onclick="ReportPointerLocation">
            Where's my mouse pointer for this button?
        </button>
    </p>
}

<p>@mousePointerMessage</p>

@code {
    private string mousePointerMessage;

    private void ReportPointerLocation(MouseEventArgs e)
    {
        mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
    }
}

EventHandlerExample3.razor:

@page "/event-handler-example-3"

@for (var i = 0; i < 4; i++)
{
    <p>
        <button @onclick="ReportPointerLocation">
            Where's my mouse pointer for this button?
        </button>
    </p>
}

<p>@mousePointerMessage</p>

@code {
    private string mousePointerMessage;

    private void ReportPointerLocation(MouseEventArgs e)
    {
        mousePointerMessage = $"Mouse coordinates: {e.ScreenX}:{e.ScreenY}";
    }
}

Podporované EventArgs jsou uvedené v následující tabulce.

Událost Třída Poznámky k DOM
Schránka ClipboardEventArgs
Táhnout DragEventArgs DataTransfer a DataTransferItem podržte přetažená data položek.

Implementujte přetažení do Blazor aplikací pomocíJS vzájemné spolupráce s rozhraním API pro přetažení HTML.
Chyba ErrorEventArgs
Událost EventArgs EventHandlers obsahuje atributy pro konfiguraci mapování mezi názvy událostí a typy argumentů událostí.
Zaměření FocusEventArgs Nezahrnuje podporu pro relatedTarget.
Vstup ChangeEventArgs
Klávesnice KeyboardEventArgs
Myš MouseEventArgs
Mouse pointer PointerEventArgs
Kolečko myši WheelEventArgs
Průběh ProgressEventArgs
Dotykové ovládání TouchEventArgs TouchPoint představuje jeden kontaktní bod na dotykovém zařízení.

Další informace naleznete v následujících zdrojích:

Vlastní argumenty událostí

Blazor podporuje vlastní argumenty událostí, které umožňují předat libovolné data obslužným rutinům událostí .NET s vlastními událostmi.

Obecná konfigurace

Vlastní události s argumenty vlastních událostí jsou obecně povoleny pomocí následujících kroků.

V JavaScriptu definujte funkci pro sestavení objektu argumentu vlastní události ze zdrojové události:

function eventArgsCreator(event) { 
  return {
    customProperty1: 'any value for property 1',
    customProperty2: event.srcElement.id
  };
}

Parametr event je událost MODELU DOM (dokumentace k MDN).

Zaregistrujte vlastní událost pomocí předchozí obslužné rutiny v inicializátoru JavaScriptu. Zadejte odpovídající název browserEventNameudálosti prohlížeče, který je v příkladu uvedeném v této části click určen pro výběr tlačítka v uživatelském rozhraní.

wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js{PACKAGE ID/ASSEMBLY NAME}(zástupný symbol je ID balíčku nebo název sestavení aplikace):

Blazor Web AppPro:

export function afterWebStarted(blazor) {
  blazor.registerCustomEventType('customevent', {
    browserEventName: 'click',
    createEventArgs: eventArgsCreator
  });
}

Pro aplikaci Blazor Server nebo Blazor WebAssembly aplikaci:

export function afterStarted(blazor) {
  blazor.registerCustomEventType('customevent', {
    browserEventName: 'click',
    createEventArgs: eventArgsCreator
  });
}

Volání registerCustomEventType se provádí ve skriptu pouze jednou pro každou událost.

Pro volání registerCustomEventTypepoužijte blazor parametr (malá písmena b) poskytnutý Blazor počáteční událostí. I když registrace je platná při použití objektu Blazor (velká písmena B), upřednostňovaným přístupem je použití parametru.

Název vlastní události v customevent předchozím příkladu nesmí odpovídat názvu rezervované Blazor události. Rezervované názvy najdete v referenčním zdroji Blazor architektury (viz volání registerBuiltInEventType funkce).

Poznámka:

Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Definujte třídu pro argumenty události:

namespace BlazorSample.CustomEvents;

public class CustomEventArgs : EventArgs
{
    public string? CustomProperty1 {get; set;}
    public string? CustomProperty2 {get; set;}
}

Projděte si vlastní událost s argumenty události přidáním [EventHandler] anotace atributu pro vlastní událost:

  • Aby kompilátor mohl najít [EventHandler] třídu, musí být umístěn do souboru třídy jazyka C# (.cs), což z něj dělá normální třídu nejvyšší úrovně.
  • Označte třídu public.
  • Třída nevyžaduje členy.
  • Třída musí být volána "EventHandlers", aby byla nalezena kompilátoremRazor.
  • Umístěte třídu do oboru názvů specifického pro vaši aplikaci.
  • Importujte obor názvů do Razor komponenty (.razor), kde se událost používá.
using Microsoft.AspNetCore.Components;

namespace BlazorSample.CustomEvents;

[EventHandler("oncustomevent", typeof(CustomEventArgs),
    enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
{
}

Zaregistrujte obslužnou rutinu události na jednom nebo více elementech HTML. Přístup k datům předanými z JavaScriptu v metodě obslužné rutiny delegáta:

@using BlazorSample.CustomEvents

<button id="buttonId" @oncustomevent="HandleCustomEvent">Handle</button>

@if (!string.IsNullOrEmpty(propVal1) && !string.IsNullOrEmpty(propVal2))
{
    <ul>
        <li>propVal1: @propVal1</li>
        <li>propVal2: @propVal2</li>
    </ul>
}

@code
{
    private string? propVal1;
    private string? propVal2;

    private void HandleCustomEvent(CustomEventArgs eventArgs)
    {
        propVal1 = eventArgs.CustomProperty1;
        propVal2 = eventArgs.CustomProperty2;
    }
}

@oncustomevent Pokud IntelliSense atribut nerozpozná, ujistěte se, že komponenta nebo _Imports.razor soubor obsahuje @using příkaz pro obor názvů obsahující EventHandler třídu.

Při každém vyvolání vlastní události v modelu DOM se obslužná rutina události zavolá s daty předanými z JavaScriptu.

Pokud se pokoušíte aktivovat vlastní událost, bubbles musíte ji povolit nastavením jeho hodnoty na truehodnotu . V opačném případě se událost nedosahuje Blazor obslužné rutiny pro zpracování do třídy vlastních [EventHandler] atributů jazyka C#. Další informace najdete v tématu Web Docs MDN: Bublání událostí.

Příklad události vložení vlastní schránky

Následující příklad obdrží vlastní událost vložení schránky, která zahrnuje čas vložení a vložený text uživatele.

Deklarujte vlastní název (oncustompaste) pro událost a třídu .NET (CustomPasteEventArgs), která má obsahovat argumenty události pro tuto událost:

CustomEvents.cs:

using Microsoft.AspNetCore.Components;

namespace BlazorSample.CustomEvents;

[EventHandler("oncustompaste", typeof(CustomPasteEventArgs), 
    enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers
{
}

public class CustomPasteEventArgs : EventArgs
{
    public DateTime EventTimestamp { get; set; }
    public string? PastedData { get; set; }
}

Přidejte kód JavaScriptu pro zadání dat pro EventArgs podtřídu s předchozí obslužnou rutinou v inicializátoru JavaScriptu. Následující příklad zpracovává pouze vkládání textu, ale můžete použít libovolná javascriptová rozhraní API pro práci s uživateli, kteří vložili jiné typy dat, jako jsou obrázky.

wwwroot/{PACKAGE ID/ASSEMBLY NAME}.lib.module.js:

Blazor Web AppPro:

export function afterWebStarted(blazor) {
  blazor.registerCustomEventType('custompaste', {
    browserEventName: 'paste',
    createEventArgs: event => {
      return {
        eventTimestamp: new Date(),
        pastedData: event.clipboardData.getData('text')
      };
    }
  });
}

Pro aplikaci Blazor Server nebo Blazor WebAssembly aplikaci:

export function afterStarted(blazor) {
  blazor.registerCustomEventType('custompaste', {
    browserEventName: 'paste',
    createEventArgs: event => {
      return {
        eventTimestamp: new Date(),
        pastedData: event.clipboardData.getData('text')
      };
    }
  });
}

V předchozím příkladu {PACKAGE ID/ASSEMBLY NAME} zástupný symbol názvu souboru představuje ID balíčku nebo název sestavení aplikace.

Poznámka:

Pro volání registerCustomEventTypepoužijte blazor parametr (malá písmena b) poskytnutý Blazor počáteční událostí. I když registrace je platná při použití objektu Blazor (velká písmena B), upřednostňovaným přístupem je použití parametru.

Předchozí kód říká prohlížeči, že když dojde k nativní paste události:

  • Vyvolání custompaste události
  • Zadejte data argumentů události pomocí vlastní logiky uvedené:

Konvence názvů událostí se mezi .NET a JavaScriptem liší:

  • V .NET mají názvy událostí předponu "on".
  • V JavaScriptu nemají názvy událostí předponu.

V komponentě Razor připojte vlastní obslužnou rutinu k elementu.

CustomPasteArguments.razor:

@page "/custom-paste-arguments"
@using BlazorSample.CustomEvents

<label>
    Try pasting into the following text box:
    <input @oncustompaste="HandleCustomPaste" />
</label>

<p>
    @message
</p>

@code {
    private string? message;

    private void HandleCustomPaste(CustomPasteEventArgs eventArgs)
    {
        message = $"At {eventArgs.EventTimestamp.ToShortTimeString()}, " +
            $"you pasted: {eventArgs.PastedData}";
    }
}

Výrazy lambda

Výrazy lambda jsou podporovány jako obslužná rutina události delegáta.

EventHandler4.razor:

@page "/event-handler-4"

<PageTitle>Event Handler 4</PageTitle>

<h1>Event Handler Example 4</h1>

<h2>@heading</h2>

<p>
    <button @onclick="@(e => heading = "New heading!!!")">
        Update heading
    </button>
</p>

@code {
    private string heading = "Initial heading";
}

EventHandlerExample4.razor:

@page "/event-handler-example-4"

<h1>@heading</h1>

<p>
    <button @onclick="@(e => heading = "New heading!!!")">
        Update heading
    </button>
</p>

@code {
    private string heading = "Initial heading";
}

EventHandlerExample4.razor:

@page "/event-handler-example-4"

<h1>@heading</h1>

<p>
    <button @onclick="@(e => heading = "New heading!!!")">
        Update heading
    </button>
</p>

@code {
    private string heading = "Initial heading";
}

EventHandlerExample4.razor:

@page "/event-handler-example-4"

<h1>@heading</h1>

<p>
    <button @onclick="@(e => heading = "New heading!!!")">
        Update heading
    </button>
</p>

@code {
    private string heading = "Initial heading";
}

EventHandlerExample4.razor:

@page "/event-handler-example-4"

<h1>@heading</h1>

<p>
    <button @onclick="@(e => heading = "New heading!!!")">
        Update heading
    </button>
</p>

@code {
    private string heading = "Initial heading";
}

Často je vhodné zavřít další hodnoty pomocí parametrů metody jazyka C#, například při iterování sady prvků. Následující příklad vytvoří tři tlačítka, z nichž každý volá UpdateHeading a předává následující data:

  • Argument události (MouseEventArgs) v e.
  • Číslo tlačítka v buttonNumber.

EventHandler5.razor:

@page "/event-handler-5"

<PageTitle>Event Handler 5</PageTitle>

<h1>Event Handler Example 5</h1>

<h2>@heading</h2>

@for (var i = 1; i < 4; i++)
{
    var buttonNumber = i;

    <p>
        <button @onclick="@(e => UpdateHeading(e, buttonNumber))">
            Button #@i
        </button>
    </p>
}

@code {
    private string heading = "Select a button to learn its position";

    private void UpdateHeading(MouseEventArgs e, int buttonNumber) => 
        heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
}

EventHandlerExample5.razor:

@page "/event-handler-example-5"

<h1>@heading</h1>

@for (var i = 1; i < 4; i++)
{
    var buttonNumber = i;

    <p>
        <button @onclick="@(e => UpdateHeading(e, buttonNumber))">
            Button #@i
        </button>
    </p>
}

@code {
    private string heading = "Select a button to learn its position";

    private void UpdateHeading(MouseEventArgs e, int buttonNumber)
    {
        heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
    }
}

EventHandlerExample5.razor:

@page "/event-handler-example-5"

<h1>@heading</h1>

@for (var i = 1; i < 4; i++)
{
    var buttonNumber = i;

    <p>
        <button @onclick="@(e => UpdateHeading(e, buttonNumber))">
            Button #@i
        </button>
    </p>
}

@code {
    private string heading = "Select a button to learn its position";

    private void UpdateHeading(MouseEventArgs e, int buttonNumber)
    {
        heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
    }
}

EventHandlerExample5.razor:

@page "/event-handler-example-5"

<h1>@heading</h1>

@for (var i = 1; i < 4; i++)
{
    var buttonNumber = i;

    <p>
        <button @onclick="@(e => UpdateHeading(e, buttonNumber))">
            Button #@i
        </button>
    </p>
}

@code {
    private string heading = "Select a button to learn its position";

    private void UpdateHeading(MouseEventArgs e, int buttonNumber)
    {
        heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
    }
}

EventHandlerExample5.razor:

@page "/event-handler-example-5"

<h1>@heading</h1>

@for (var i = 1; i < 4; i++)
{
    var buttonNumber = i;

    <p>
        <button @onclick="@(e => UpdateHeading(e, buttonNumber))">
            Button #@i
        </button>
    </p>
}

@code {
    private string heading = "Select a button to learn its position";

    private void UpdateHeading(MouseEventArgs e, int buttonNumber)
    {
        heading = $"Selected #{buttonNumber} at {e.ClientX}:{e.ClientY}";
    }
}

Vytvoření velkého počtu delegátů událostí ve smyčce může způsobit nízký výkon vykreslování. Další informace najdete v tématu o osvědčených postupech ASP.NET výkonu coreBlazor.

Nepoužívejte proměnnou smyčky přímo ve výrazu lambda, například i v předchozím příkladu smyčky for . V opačném případě se stejná proměnná používá ve všech výrazech lambda, což vede k použití stejné hodnoty ve všech výrazech lambda. Zachyťte hodnotu proměnné v místní proměnné. V předchozím příkladu:

  • Proměnná i smyčky je přiřazena .buttonNumber
  • buttonNumber se používá ve výrazu lambda.

Alternativně použijte smyčku foreach s Enumerable.Range, která netrpí předchozím problémem:

@foreach (var buttonNumber in Enumerable.Range(1, 3))
{
    <p>
        <button @onclick="@(e => UpdateHeading(e, buttonNumber))">
            Button #@buttonNumber
        </button>
    </p>
}

EventCallback

Běžný scénář s vnořenými komponentami spouští metodu v nadřazené komponentě, když dojde k události podřízené komponenty. Událost onclick , ke které dochází v podřízené komponentě, je běžným případem použití. Pokud chcete zobrazit události napříč komponentami, použijte příkaz EventCallback. Nadřazená komponenta může přiřadit metodu zpětného volání podřízené EventCallbacksoučásti .

Následující Child komponenta ukazuje, jak je obslužná rutina onclick tlačítka nastavena pro příjem delegáta EventCallback z ukázky ParentComponent. Typ EventCallback je zadán s MouseEventArgs, což je vhodné pro onclick událost z periferního zařízení.

Child.razor:

<p>
    <button @onclick="OnClickCallback">
        Trigger a Parent component method
    </button>
</p>

@code {
    [Parameter]
    public string? Title { get; set; }

    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    [Parameter]
    public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<p>
    <button @onclick="OnClickCallback">
        Trigger a Parent component method
    </button>
</p>

@code {
    [Parameter]
    public string? Title { get; set; }

    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    [Parameter]
    public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<p>
    <button @onclick="OnClickCallback">
        Trigger a Parent component method
    </button>
</p>

@code {
    [Parameter]
    public string? Title { get; set; }

    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    [Parameter]
    public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<p>
    <button @onclick="OnClickCallback">
        Trigger a Parent component method
    </button>
</p>

@code {
    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
}
<p>
    <button @onclick="OnClickCallback">
        Trigger a Parent component method
    </button>
</p>

@code {
    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

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

Komponenta Parent nastaví podřízenou EventCallback<TValue> (OnClickCallback) na svou ShowMessage metodu.

ParentChild.razor:

@page "/parent-child"

<PageTitle>Parent Child</PageTitle>

<h1>Parent Child Example</h1>

<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
    Content of the child component is supplied by the parent component.
</Child>

<p>@message</p>

@code {
    private string? message;

    private void ShowMessage(MouseEventArgs e) => 
        message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
}

Parent.razor:

@page "/parent"

<h1>Parent-child example</h1>

<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
    Content of the child component is supplied by the parent component.
</Child>

<p>@message</p>

@code {
    private string? message;

    private void ShowMessage(MouseEventArgs e)
    {
        message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
    }
}

Parent.razor:

@page "/parent"

<h1>Parent-child example</h1>

<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
    Content of the child component is supplied by the parent component.
</Child>

<p>@message</p>

@code {
    private string? message;

    private void ShowMessage(MouseEventArgs e)
    {
        message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
    }
}

Parent.razor:

@page "/parent"

<h1>Parent-child example</h1>

<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
    Content of the child component is supplied by the parent component.
</Child>

<p>@message</p>

@code {
    private string message;

    private void ShowMessage(MouseEventArgs e)
    {
        message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
    }
}

Parent.razor:

@page "/parent"

<h1>Parent-child example</h1>

<Child Title="Panel Title from Parent" OnClickCallback="ShowMessage">
    Content of the child component is supplied by the parent component.
</Child>

<p>@message</p>

@code {
    private string message;

    private void ShowMessage(MouseEventArgs e)
    {
        message = $"Blaze a new trail with Blazor! ({e.ScreenX}:{e.ScreenY})";
    }
}

Když je tlačítko vybráno v :ChildComponent

  • Volá Parent se ShowMessage metoda komponenty. message se aktualizuje a zobrazí v komponentě Parent .
  • Volání StateHasChanged není vyžadováno v metodě zpětného volání (ShowMessage). StateHasChanged je volána automaticky k opětovnému vyřazuje komponentu Parent , stejně jako podřízené události aktivují rerendering komponent v obslužných rutinách událostí, které se spouští v rámci podřízené. Další informace najdete v tématu Vykreslování komponent ASP.NET Core Razor.

Použití EventCallback a EventCallback<TValue> pro zpracování událostí a vazby parametrů komponent.

Preferujte silné typy EventCallback<TValue> nad EventCallback. EventCallback<TValue> poskytuje vylepšenou zpětnou vazbu k chybám při použití nevhodného typu, který uživatele komponenty vede ke správné implementaci. Podobně jako u jiných obslužných rutin událostí uživatelského rozhraní je zadání parametru události volitelné. Použijte EventCallback , když se zpětnému volání nepředá žádná hodnota.

EventCallback a EventCallback<TValue> povolte asynchronní delegáty. EventCallback je slabě napsaný a umožňuje předat libovolný argument typu v InvokeAsync(Object). EventCallback<TValue> je silného typu a vyžaduje předání T argumentu, InvokeAsync(T) který je možné TValuepřiřadit .

Vyvolání nebo EventCallback<TValue> s parametrem EventCallback InvokeAsync a operátorem await:Task

await OnClickCallback.InvokeAsync({ARGUMENT});

V předchozím příkladu {ARGUMENT} je zástupný symbol nepovinným argumentem.

Následující příklad nadřazeného podřízeného objektu ukazuje techniku.

Child2.razor:

<h3>Child2 Component</h3>

<button @onclick="TriggerEvent">Click Me</button>

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

    private async Task TriggerEvent()
    {
        await OnClickCallback.InvokeAsync("Blaze It!");
    }
}

ParentChild2.razor:

@page "/parent-child-2"

<PageTitle>Parent Child 2</PageTitle>

<h1>Parent Child 2 Example</h1>

<div>
    <Child2 OnClickCallback="(value) => { message1 = value; }" />
    @message1
</div>

<div>
    <Child2 OnClickCallback=
        "async (value) => { await Task.Delay(2000); message2 = value; }" /> 
    @message2
</div>

@code {
    private string message1 = string.Empty;
    private string message2 = string.Empty;
}

Druhý výskyt Child2 komponenty ukazuje asynchronní zpětné volání a nová message2 hodnota je přiřazena a vykreslena se zpožděním dvou sekund.

Zabránění výchozím akcím

Atribut direktivy @on{DOM EVENT}:preventDefault použijte, pokud chcete zabránit výchozí akci události, kde {DOM EVENT} zástupný symbol je událost MODELU DOM.

Když je na vstupním zařízení vybrána klávesa a fokus prvku je v textovém poli, prohlížeč obvykle zobrazí znak klíče v textovém poli. V následujícím příkladu je výchozí chování zabráněno zadáním atributu @onkeydown:preventDefault direktivy. Když je fokus <input> na prvku, čítač zvýší s klávesovou sekvencí Shift++. Znak + není přiřazen k hodnotě elementu <input> . Další informace o keydownudálosti najdete v tématu MDN Web Docs: Document: keydown události.

EventHandler6.razor:

@page "/event-handler-6"

<PageTitle>Event Handler 6</PageTitle>

<h1>Event Handler Example 6</h1>

<p>For this example, give the <code><input></code> focus.</p>

<p>
    <label>
        Count of '+' key presses: 
        <input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
    </label>
</p>

@code {
    private int count = 0;

    private void KeyHandler(KeyboardEventArgs e)
    {
        if (e.Key == "+")
        {
            count++;
        }
    }
}

EventHandlerExample6.razor:

@page "/event-handler-example-6"

<p>
    <input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
</p>

@code {
    private int count = 0;

    private void KeyHandler(KeyboardEventArgs e)
    {
        if (e.Key == "+")
        {
            count++;
        }
    }
}

EventHandlerExample6.razor:

@page "/event-handler-example-6"

<p>
    <input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
</p>

@code {
    private int count = 0;

    private void KeyHandler(KeyboardEventArgs e)
    {
        if (e.Key == "+")
        {
            count++;
        }
    }
}

EventHandlerExample6.razor:

@page "/event-handler-example-6"

<p>
    <input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
</p>

@code {
    private int count = 0;

    private void KeyHandler(KeyboardEventArgs e)
    {
        if (e.Key == "+")
        {
            count++;
        }
    }
}

EventHandlerExample6.razor:

@page "/event-handler-example-6"

<p>
    <input value="@count" @onkeydown="KeyHandler" @onkeydown:preventDefault />
</p>

@code {
    private int count = 0;

    private void KeyHandler(KeyboardEventArgs e)
    {
        if (e.Key == "+")
        {
            count++;
        }
    }
}

Určení atributu @on{DOM EVENT}:preventDefault bez hodnoty je ekvivalentní @on{DOM EVENT}:preventDefault="true".

Výraz je také povolená hodnota atributu. V následujícím příkladu shouldPreventDefault bool je pole nastavené na hodnotu nebo true false:

<input @onkeydown:preventDefault="shouldPreventDefault" />

...

@code {
    private bool shouldPreventDefault = true;
}

Zastavení šíření událostí

Pomocí atributu @on{DOM EVENT}:stopPropagation direktivy zastavte šíření událostí v rámci Blazor oboru. {DOM EVENT} je zástupný symbol pro událost MODELU DOM.

stopPropagation Účinek atributu direktivy je omezen na Blazor rozsah a nevztahuje se na HTML DOM. Události se musí rozšířit do kořenového adresáře HTML DOM, aby Blazor na ně mohly reagovat. Pokud chcete mechanismus zabránit šíření událostí HTML DOM, zvažte následující přístup:

V následujícím příkladu zaškrtnutím políčka zabráníte tomu, aby se události kliknutí z druhého podřízeného <div> objektu rozšířily do nadřazeného <div>objektu . Vzhledem k tomu, že rozšířené události kliknutí obvykle aktivují metodu OnSelectParentDiv , výběr druhého podřízeného <div> výsledku zobrazí nadřazenou <div> zprávu, pokud není políčko zaškrtnuté.

EventHandler7.razor:

@page "/event-handler-7"

<PageTitle>Event Handler 7</PageTitle>

<h1>Event Handler Example 7</h1>

<div>
    <b>stopPropagation</b>: @stopPropagation
</div>

<div>
    <button @onclick="StopPropagation">
        Stop Propagation (stopPropagation = true)
    </button>
    <button @onclick="EnablePropagation">
        Enable Propagation (stopPropagation = false)
    </button>
</div>

<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
    <h3>Parent div</h3>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
        Child div that never stops propagation to the parent div when 
        selected.
    </div>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv" 
            @onclick:stopPropagation="stopPropagation">
        Child div that stops propagation when selected if 
        <b>stopPropagation</b> is <b>true</b>.
    </div>
</div>

<p>
    @message
</p>

@code {
    private bool stopPropagation = false;
    private string? message;

    private void StopPropagation() => stopPropagation = true;

    private void EnablePropagation() => stopPropagation = false;

    private void OnSelectParentDiv() => 
        message = $"The parent div was selected. {DateTime.Now}";

    private void OnSelectChildDiv() => 
        message = $"The child div was selected. {DateTime.Now}";
}

EventHandlerExample7.razor:

@page "/event-handler-example-7"

<div>
    <b>stopPropagation</b>: @stopPropagation
</div>

<div>
    <button @onclick="StopPropagation">
        Stop Propagation (stopPropagation = true)
    </button>
    <button @onclick="EnablePropagation">
        Enable Propagation (stopPropagation = false)
    </button>
</div>

<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
    <h3>Parent div</h3>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
        Child div that never stops propagation to the parent div when 
        selected.
    </div>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv" 
            @onclick:stopPropagation="stopPropagation">
        Child div that stops propagation when selected if 
        <b>stopPropagation</b> is <b>true</b>.
    </div>
</div>

<p>
    @message
</p>

@code {
    private bool stopPropagation = false;
    private string? message;

    private void StopPropagation() => stopPropagation = true;

    private void EnablePropagation() => stopPropagation = false;

    private void OnSelectParentDiv() =>
        message = $"The parent div was selected. {DateTime.Now}";

    private void OnSelectChildDiv() =>
        message = $"The child div was selected. {DateTime.Now}";
}

EventHandlerExample7.razor:

@page "/event-handler-example-7"

<div>
    <b>stopPropagation</b>: @stopPropagation
</div>

<div>
    <button @onclick="StopPropagation">
        Stop Propagation (stopPropagation = true)
    </button>
    <button @onclick="EnablePropagation">
        Enable Propagation (stopPropagation = false)
    </button>
</div>

<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
    <h3>Parent div</h3>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
        Child div that never stops propagation to the parent div when 
        selected.
    </div>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv" 
            @onclick:stopPropagation="stopPropagation">
        Child div that stops propagation when selected if 
        <b>stopPropagation</b> is <b>true</b>.
    </div>
</div>

<p>
    @message
</p>

@code {
    private bool stopPropagation = false;
    private string? message;

    private void StopPropagation() => stopPropagation = true;

    private void EnablePropagation() => stopPropagation = false;

    private void OnSelectParentDiv() =>
        message = $"The parent div was selected. {DateTime.Now}";

    private void OnSelectChildDiv() =>
        message = $"The child div was selected. {DateTime.Now}";
}

EventHandlerExample7.razor:

@page "/event-handler-example-7"

<div>
    <b>stopPropagation</b>: @stopPropagation
</div>

<div>
    <button @onclick="StopPropagation">
        Stop Propagation (stopPropagation = true)
    </button>
    <button @onclick="EnablePropagation">
        Enable Propagation (stopPropagation = false)
    </button>
</div>

<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
    <h3>Parent div</h3>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
        Child div that never stops propagation to the parent div when 
        selected.
    </div>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv" 
            @onclick:stopPropagation="stopPropagation">
        Child div that stops propagation when selected if 
        <b>stopPropagation</b> is <b>true</b>.
    </div>
</div>

<p>
    @message
</p>

@code {
    private bool stopPropagation = false;
    private string message;

    private void StopPropagation() => stopPropagation = true;

    private void EnablePropagation() => stopPropagation = false;

    private void OnSelectParentDiv() =>
        message = $"The parent div was selected. {DateTime.Now}";

    private void OnSelectChildDiv() =>
        message = $"The child div was selected. {DateTime.Now}";
}

EventHandlerExample7.razor:

@page "/event-handler-example-7"

<div>
    <b>stopPropagation</b>: @stopPropagation
</div>

<div>
    <button @onclick="StopPropagation">
        Stop Propagation (stopPropagation = true)
    </button>
    <button @onclick="EnablePropagation">
        Enable Propagation (stopPropagation = false)
    </button>
</div>

<div class="m-1 p-1 border border-primary" @onclick="OnSelectParentDiv">
    <h3>Parent div</h3>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv">
        Child div that never stops propagation to the parent div when 
        selected.
    </div>

    <div class="m-1 p-1 border" @onclick="OnSelectChildDiv" 
            @onclick:stopPropagation="stopPropagation">
        Child div that stops propagation when selected if 
        <b>stopPropagation</b> is <b>true</b>.
    </div>
</div>

<p>
    @message
</p>

@code {
    private bool stopPropagation = false;
    private string message;

    private void StopPropagation() => stopPropagation = true;

    private void EnablePropagation() => stopPropagation = false;

    private void OnSelectParentDiv() =>
        message = $"The parent div was selected. {DateTime.Now}";

    private void OnSelectChildDiv() =>
        message = $"The child div was selected. {DateTime.Now}";
}

Fokus na prvek

Volání FocusAsync odkazu na prvek za účelem zaměření prvku v kódu. V následujícím příkladu vyberte tlačítko pro fokus prvku <input> .

EventHandler8.razor:

@page "/event-handler-8"

<PageTitle>Event Handler 8</PageTitle>

<h1>Event Handler Example 8</h1>

<p>Select the button to give the <code><input></code> focus.</p>

<p>
    <label>
        Input: 
        <input @ref="exampleInput" />
    </label>
    
</p>

<button @onclick="ChangeFocus">
    Focus the Input Element
</button>

@code {
    private ElementReference exampleInput;

    private async Task ChangeFocus()
    {
        await exampleInput.FocusAsync();
    }
}

EventHandlerExample8.razor:

@page "/event-handler-example-8"

<p>
    <input @ref="exampleInput" />
</p>

<button @onclick="ChangeFocus">
    Focus the Input Element
</button>

@code {
    private ElementReference exampleInput;

    private async Task ChangeFocus()
    {
        await exampleInput.FocusAsync();
    }
}

EventHandlerExample8.razor:

@page "/event-handler-example-8"

<p>
    <input @ref="exampleInput" />
</p>

<button @onclick="ChangeFocus">
    Focus the Input Element
</button>

@code {
    private ElementReference exampleInput;

    private async Task ChangeFocus()
    {
        await exampleInput.FocusAsync();
    }
}