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říkladclick
). - 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:
EventArgs
třídy v referenčním zdroji ASP.NET Core (větev dotnet/aspnetcoremain
)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).
EventHandlers obsahuje atributy pro konfiguraci mapování mezi názvy událostí a typy argumentů událostí.
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 browserEventName
udá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í registerCustomEventType
použ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 true
hodnotu . 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í registerCustomEventType
použ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é:
- Pro pole
eventTimestamp
vytvořte nové datum. - V případě zprávy
pastedData
získejte data ze schránky jako text. Další informace naleznete v tématu MDN Web Docs: ClipboardEvent.clipboardData.
- Pro pole
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
seShowMessage
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 komponentuParent
, 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é TValue
př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 keydown
udá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:
- Získání cesty události voláním
Event.composedPath()
. - Filtrování událostí na základě složených cílů událostí (
EventTarget
).
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();
}
}