翻譯自 Waqas Anwar 2021年3月25日的文章 《A Developer’s Guide To Blazor Event Handling》 [1]

如果您正在開發互動式 Web 應用程式,根據不同的應用程式事件和使用者操作動態更新使用者介面是十分常見的做法。這些操作會觸發事件,而作為開發人員,我們的工作是使用一些事件處理技術來處理這些事件。Blazor 內建支援處理多種事件,比如 onclick、onchange 和 onmousemove 等,併為開發者提供了處理這些事件的多種方式。我將在本教程中概述 Blazor 事件處理。此外,我還將介紹如何在 Blazor 中使用事件引數和 Lambda 表示式,以及如何將附加引數傳遞給事件處理程式。

Blazor 事件處理入門

Blazor 中處理事件的基本語法如下所示:

@on[DOM EVENT]="[DELEGATE]"

在上面的語法中

  • [DOM EVENT] 是 DOM 事件的佔位符,例如 click、mouseup 等。
  • [DELEGATE] 是 C# 委託事件處理程式的佔位符。

假設您要處理按鈕單擊事件,您可以按如下方式使用上述語法:

<button @onclick="Update" />

讓我們通過一些實際的例子來更詳細地介紹一下事件處理。 在 Visual Studio 2019 中建立一個新的 Blazor Server 應用程式,然後新增一個新的 Blazor 元件 Calculator.razor

@page "/calculator"

<h3>Calculator</h3>

<div class="form-group">
<label for="number1">Number 1</label>
<input type="number" class="form-control" id="number1" @bind="number1">
</div>
<div class="form-group">
<label for="number2">Number 2</label>
<input type="number" class="form-control" id="number2" @bind="number2">
</div>
<div class="form-group">
<label><b>Total: </b>@total</label>
</div> <button class="btn btn-primary" @onclick="Calculate">Calculate</button>
<button class="btn btn-secondary" @onclick="Clear">Clear</button> @code {
private int number1 = 0;
private int number2 = 0;
private int total = 0; private void Calculate()
{
total = number1 + number2;
} private void Clear()
{
number1 = 0;
number2 = 0;
total = 0;
}
}

上面的元件中有兩個按鈕:Calculate 和 Clear,它們都處理了 onclick 事件,並呼叫了上面的 @code 程式碼塊中編寫的 CalculateClear 方法。

<button class="btn btn-primary" @onclick="Calculate">Calculate</button>
<button class="btn btn-secondary" @onclick="Clear">Clear</button>

如果您執行這個簡單的示例,將看到類似於以下內容的頁面。在文字框中輸入一些數字,然後按下按鈕檢視事件處理的效果。

如下面的程式碼片段所示,Blazor 還支援非同步委託事件處理程式。這些處理程式型別會返回一個 Task,在其內部我們可以使用 await 關鍵字呼叫非同步方法。

private async Task Clear()
{
await Task.Delay(10); number1 = 0;
number2 = 0;
total = 0;
}

理解 Blazor 事件引數

大部分 Blazor 事件支援事件引數,這些引數是攜帶觸發事件的相關資訊的物件。例如,KeyboardEventArgs 可以為我們提供使用者按下的按鍵的詳細資訊。

讓我們建立一個帶有標準的 HTML div 元素的基本元件,如下所示。

@page "/mouseevents"

<h3>Mouse Events</h3>

<div style="width: 400px; height: 400px; background: lightblue" @onmousemove="Move"></div>
<label><b>Coordinates: </b>@coordinates</label> @code {
private string coordinates = ""; private void Move(MouseEventArgs e)
{
coordinates = $"{e.ScreenX}:{e.ScreenY}";
}
}

上面的 div 元素處理 onmousemove 事件並將 MouseEventArgs 傳遞給方法名為 Move 的事件處理程式。然後,Move 事件處理程式使用 MouseEventArgs 類中提供的 ScreenXScreenY 屬性,用滑鼠的 X 和 Y 位置更新本地欄位 coordinates。執行應用程式,並嘗試在 div 中移動滑鼠,您將看到座標會實時更新。

Blazor 支援大量的 EventArgs 物件,但最常用的 EventArgs 如下表所示:

事件 DOM 事件
焦點(Focus) FocusEventArgs onfocus, onblur, onfocusin, onfocusout
輸入(Input) ChangeEventArgs onchange, oninput
鍵盤(Keyboard) KeyboardEventArgs onkeydown, onkeypress, onkeyup
滑鼠(Mouse) MouseEventArgs onclick, oncontextmenu, ondblclick, onmousedown, onmouseup, onmouseover, onmousemove, onmouseout
滑鼠滾輪(Mouse wheel) WheelEventArgs onwheel, onmousewheel
觸控(Touch) TouchEventArgs ontouchstart, ontouchend, ontouchmove, ontouchenter, ontouchleave, ontouchcancel

您可以在微軟 Blazor 文件頁面[2]上看到 EventArgs 的完整列表。

在 Blazor 事件中使用 Lambda 表示式

Blazor 還支援將 Lambda 表示式作為委託事件處理程式。您應當只在簡單的用例中使用這些表示式,如果有很多的程式碼要執行,應避免使用 Lambda 表示式。讓我們修改一下前面的 Calculator 示例,這次使用 Lambda 表示式替代上面的 CalculateClear 方法。

@page "/calculator"
<h3>Calculator</h3>
<div class="form-group">
<label for="number1">Number 1</label>
<input type="number" class="form-control" id="number1" @bind="number1">
</div>
<div class="form-group">
<label for="number2">Number 2</label>
<input type="number" class="form-control" id="number2" @bind="number2">
</div>
<div class="form-group">
<label><b>Total: </b>@total</label>
</div> <button class="btn btn-primary" @onclick="@(e => total = number1 + number2)">Calculate</button>
<button class="btn btn-secondary" @onclick="@(e => total = number1 = number2 = 0)">Clear</button> @code {
private int number1 = 0;
private int number2 = 0;
private int total = 0;
}

向事件處理程式傳遞附加引數

有時,我們希望根據每個應用程式的需要向事件處理程式傳遞額外的引數。例如,在一個迴圈中,您可能希望將迴圈迭代索引號傳遞給事件引數,以便您知道此事件處理程式是針對迴圈中的哪一項執行的。另一個簡單的例子是,從兩個或多個控制元件呼叫相同的事件處理程式,並傳遞控制元件的引用以處理事件。讓我們用一個基礎的例子來介紹一下這個概念。依照下面的程式碼片段再次修改 Calculator 的程式碼。

<div class="form-group">
<label for="number1">Number 1</label>
<input type="number" class="form-control" id="number1" @bind="number1">
</div> <div class="form-group">
<label for="number2">Number 2</label>
<input type="number" class="form-control" id="number2" @bind="number2">
</div> <div class="form-group">
<label><b>Total: </b>@total</label>
</div> <button class="btn btn-primary" @onclick="@(e => Calculate(e, 1))">Add</button>
<button class="btn btn-primary" @onclick="@(e => Calculate(e, 2))">Subtract</button> <button class="btn btn-secondary" @onclick="Clear">Clear</button> @code {
private int number1 = 0;
private int number2 = 0;
private int total = 0; private void Calculate(MouseEventArgs e, int buttonType)
{
switch (buttonType)
{
case 1:
total = number1 + number2;
break;
case 2:
total = number1 - number2;
break;
}
} private void Clear()
{
number1 = 0;
number2 = 0;
total = 0;
}
}

在上面程式碼片段中,重要的兩行如下,我將一個附加引數傳遞給了 Calculate 方法,其值分別為 12

<button class="btn btn-primary" @onclick="@(e => Calculate(e, 1))">Add</button>
<button class="btn btn-primary" @onclick="@(e => Calculate(e, 2))">Subtract</button>

方法 Calculate 的程式碼也略有修改,因為現在它接受一個額外的引數 buttonType。在此方法中,我們根據 buttonType 引數的值進行加法或減法運算。

private void Calculate(MouseEventArgs e, int buttonType)
{
switch (buttonType)
{
case 1:
total = number1 + number2;
break
case 2:
total = number1 - number2;
break;
}
}

再次執行應用程式,並嘗試點選 AddSubtract 方法,您會看到相同的 Calculate 方法給了我們不同的結果。

相關閱讀:

作者 : Waqas Anwar

翻譯 : 技術譯站

連結 : 英文原文


  1. https://www.ezzylearning.net/tutorial/a-developers-guide-to-blazor-event-handling A Developer’s Guide To Blazor Event Handling

  2. https://docs.microsoft.com/zh-cn/aspnet/core/blazor/components/event-handling ASP.NET Core Blazor 事件處理