Blazor University (6)组件 — 组件事件
原文鏈接:https://blazor-university.com/components/component-events/
組件事件
源代碼[1]
EventCallback<T> 類是一個特殊的 Blazor 類,可以作為參數(shù)公開,以便組件可以在發(fā)生感興趣的事情時輕松通知使用者。
一旦聲明了 EventCallback<T> 類型的公共屬性并使用 [Parameter] 屬性進行了修飾,使用組件就可以在 Razor 標(biāo)記中指定觸發(fā)事件時要調(diào)用的方法。
向 Counter 組件添加事件
在新的 Blazor 應(yīng)用中,編輯 /Pages/Counter.razor 文件并添加新的回調(diào)參數(shù)。
[Parameter] public?EventCallback<int>?OnMultipleOfThree?{?get;?set;?}這聲明了一個名為 OnMultipleOfThree 的新 EventCallback,任何使用組件都可以注冊它。<int> 指定事件回調(diào)發(fā)出的值將是 System.Int32。
現(xiàn)在,如果我們編輯 IncrementCount 方法,我們可以在計數(shù)器增加到 3 的倍數(shù)時發(fā)出此事件。
private?async?Task?IncrementCount() {currentCount++;if?(currentCount?%?3?==?0)await?OnMultipleOfThree.InvokeAsync(currentCount); }訂閱 EventCallback
編輯 /Pages/Index.razor 頁面,以便我們嵌入 Counter 組件并訂閱其 OnMultipleOfThree 事件。將其標(biāo)記更改為以下內(nèi)容。
@page?"/"Last?multiple?of?three?=?@LastMultipleOfThree<Counter?OnMultipleOfThree=@UpdateLastMultipleOfThreeValue/>@code {int?LastMultipleOfThree?=?0;private?void?UpdateLastMultipleOfThreeValue(int?value){LastMultipleOfThree?=?value;} }第 9 行
聲明一個 int 類型的類成員,它存儲 3 值的最后一個倍數(shù)。
第 3 行
顯示 LastMultipleOfThree 的值
第 5 行
嵌入 Counter 組件并設(shè)置其 OnMultipleOfThree 事件以在發(fā)出事件時執(zhí)行 UpdateLastMultipleOfThreeValue 方法。
第 11 行
從事件接收到的值用于更新 LastMultipleOfThree 的值。
EventCallback和 .NET 事件之間的區(qū)別
單播與多播
最顯著的區(qū)別是 EventCallback<T> 是單播事件處理程序,而 .NET 事件是多播。Blazor EventCallback<T> 旨在分配單個值,并且只能回調(diào)單個方法。
//?Setting?a?Blazor?EventCallback <MyComponent?SomeEvent=@MyMethodToCall/>//?Setting?a?.NET?event MyComponent.SomeEvent?+=?MyMethodToCall; //?Unscrubscribing?from?the?event MyComponent.SomeEvent?-=?MyMethodToCall;類與結(jié)構(gòu)
.NET 事件(委托)是類,而 Blazor EventCallback<T> 是只讀結(jié)構(gòu)。與 .NET 委托不同,EventCallback<T> 不能為 null,因此在發(fā)出事件時無需進行任何 null 檢查。
//?Invoking?a?.NET?event MyNetEvent?.Invoke(this,?someValue);//?Invoking?a?CallbackEvent<T> MyEventCallback.InvokeAsync(someValue);等待回調(diào)
標(biāo)準(zhǔn) .NET 事件是同步的,而 Blazor EventCallback<T> 是異步的。正如我們在前面的示例代碼中看到的,EventCallback<T>.InvokeAsync 返回一個可以等待的 Task。
Razor 標(biāo)記兼容性
無法使用 [Parameter] 裝飾標(biāo)準(zhǔn) .NET 事件并通過 Razor 標(biāo)記設(shè)置它,而使用 EventCallback<T> 可以。這使我們能夠在視圖標(biāo)記本身中表達事件回調(diào),這使得開發(fā)人員的意圖更容易看到。
自動狀態(tài)變化檢測
每當(dāng)從 EventCallback<T> 調(diào)用方法時,在方法執(zhí)行后,Blazor 將在使用組件上執(zhí)行 StateHasChanged(),以便在方法調(diào)用更改狀態(tài)時重新渲染它。如果使用者的方法是通過標(biāo)準(zhǔn) .NET 事件、Action或不是由 EventCallback<T> 發(fā)起的任何其他方法回調(diào)的,則不會發(fā)生這種情況。
例如,如果我們將一個新的 [Parameter] 添加到 Action<int> 類型的 Counter 組件中,并在當(dāng)前計數(shù)是 2 的倍數(shù)時調(diào)用它,我們可以看到使用組件的渲染行為是如何受到影響的。
更改 Counter 組件以匹配以下代碼:
@page?"/counter"<h1>Counter</h1><p>Current?count:?@currentCount</p><button?class="btn?btn-primary"?@onclick=IncrementCount>Click?me</button>@code?{private?int?currentCount?=?0;[Parameter]public?Action<int>?OnMultipleOfTwoAction?{?get;?set;?}[Parameter]public?EventCallback<int>?OnMultipleOfThree?{?get;?set;?}private?async?Task?IncrementCount(){currentCount++;if?(currentCount?%?2?==?0)OnMultipleOfTwoAction?.Invoke(currentCount);if?(currentCount?%?3?==?0)await?OnMultipleOfThree.InvokeAsync(currentCount);} }第 13 行
添加了 Action<int> 類型的 [Parameter]
第 21-22 行
如果當(dāng)前計數(shù)是 2 的倍數(shù),則調(diào)用 OnMultipleOfTwoAction
現(xiàn)在更改 Index 組件,使其在值為 2 的倍數(shù)時設(shè)置回調(diào)方法,因此它也會存儲并顯示從 OnMultipleOfTwoAction 接收到的最后一個數(shù)字在使用的組件上。
@page?"/"<ul><li>Last?multiple?of?two?=?@LastMultipleOfTwo</li><li>Last?multiple?of?three?=?@LastMultipleOfThree</li> </ul><Counter?OnMultipleOfThree=@UpdateLastMultipleOfThreeValue?OnMultipleOfTwoAction=@UpdateLastMultipleOfTwoValue?/>@code {int?LastMultipleOfTwo?=?0;int?LastMultipleOfThree?=?0;private?Task?UpdateLastMultipleOfThreeValue(int?value){LastMultipleOfThree?=?value;return?Task.CompletedTask;}private?void?UpdateLastMultipleOfTwoValue(int?value){LastMultipleOfTwo?=?value;} }第 13 行
定義一個新成員來存儲從使用組件傳遞的最新“二的倍數(shù)”值
第 4 行
在用戶界面中顯示 LastMultipleOfTwo 的值
第 9 行
在使用的組件上設(shè)置 OnMultipleOfTwo 以便在當(dāng)前值是 2 的倍數(shù)時通知我們的組件
第 24 行
記錄使用組件通知我們的最后 2 的倍數(shù)
當(dāng)我們現(xiàn)在運行應(yīng)用程序并多次單擊按鈕時,我們會看到當(dāng)通過 Action<int> 回調(diào) UpdateLastMultipleOfTwoValue 時,視圖沒有更新,但是當(dāng)下一次單擊通過 EventCallback<int> 回調(diào) UpdateLastMultipleOfThreeValue 時,視圖更新并顯示兩者的最新值。
事件順序| 1 | 無 | N/A |
| 2 | Action<int> | No |
| 3 | Action<int> EventCallback<int> | Yes |
| 4 | Action<int> | No |
| 5 | None | N/A |
| 6 | Action<int> ?EventCallback<int> | Yes |
EventCallback<T> 通?;卣{(diào)帶有簽名 private Task SomeName(T value)的方法——其中方法的暴露級別并不重要。但是,Blazor 將允許我們設(shè)置一個 EventCallback<T> 來回調(diào)具有幾個變體的方法。
如果我們的方法不執(zhí)行任何異步操作,那么下面的實現(xiàn)可能會開始變得乏味:
public?Task?SomethingHappenedInChildComponent(string?value) {//?Do?something?with?valuereturn?Task.CompletedTask; }因此,Blazor 將允許我們設(shè)置 EventCallback<T> 以回調(diào)具有 void 返回類型的方法。
public?void?SomethingHappenedInChildComponent(string?value) {//?Do?something?with?value }有時我們只想知道一個事件何時發(fā)生,而不是對它傳遞的值感興趣。Blazor 還將回調(diào)一個排除 value 參數(shù)的方法。
//?Either public?void?SomethingHappenedInChildComponent() {//?Do?something?that?doesn't?need?the?value }//?Or public?Task?SomethingHappenedInChildComponent() {//?Do?some?asynchronous?work?that?doesn't?need?the?valuereturn?SomeTask; }瀏覽器 DOM 事件
呈現(xiàn)任何標(biāo)記時,可以在呈現(xiàn)的 HTML 元素上分配標(biāo)準(zhǔn) JavaScript 事件,以便執(zhí)行我們自己的 Blazor C# 方法。例如,我們在其他地方的許多示例中使用了 @onclick 指令:
<button?@onclick=ButtonClicked>Click?me</button>這些事件指令在 Visual Studio 編輯器中具有完整的 IntelliSense 支持,因此開始鍵入 @ 符號應(yīng)該會為我們提供可用指令的完整列表,以及標(biāo)識事件在我們的事件處理程序中傳遞給我們的參數(shù)類類型的描述。DOM 事件以 @on 開頭。
將“@onabort”屬性設(shè)置為提供的字符串或委托值。委托值應(yīng)為“Microsoft.AspNetCore.Components.Web.ProgressEventArgs”類型警告:在編寫完全在服務(wù)器上運行的 Blazor 應(yīng)用程序時,Blazor 將 hook 瀏覽器中的事件并將它們發(fā)送到服務(wù)器,以便可以調(diào)用我們的 C# 方法。這可能會導(dǎo)致頻繁觸發(fā)的事件(例如 onmousemove)明顯變慢。
注意: 因為 C# 方法的 JavaScript 調(diào)用是異步的,這意味著在 C# 方法中我們不能像在 JavaScript 中那樣取消事件。這是因為取消瀏覽器 DOM 事件是一個同步操作,當(dāng)我們的 C# 被異步調(diào)用時,取消事件已經(jīng)太遲了。
可用的 DOM 事件及其參數(shù)類型包括:
一般事件
| onactivate | EventArgs |
| onbeforeactivate | EventArgs |
| onbeforedeactivate | EventArgs |
| ondeactivate | EventArgs |
| onended | EventArgs |
| onfullscreenchange | EventArgs |
| onfullscreenerror | EventArgs |
| onloadeddata | EventArgs |
| onloadedmetadata | EventArgs |
| onpointerlockchange | EventArgs |
| onpointerlockerror | EventArgs |
| onreadystatechange | EventArgs |
| onscroll | EventArgs |
焦點事件
| onfocus | FocusEventArgs |
| onblur | FocusEventArgs |
| onfocusin | FocusEventArgs |
| onfocusout | FocusEventArgs |
鼠標(biāo)事件
| onmouseover | MouseEventArgs |
| onmouseout | MouseEventArgs |
| onmousemove | MouseEventArgs |
| onmousedown | MouseEventArgs |
| onmouseup | MouseEventArgs |
| onclick | MouseEventArgs |
| ondblclick | MouseEventArgs |
| oncontextmenu | MouseEventArgs |
| onwheel | WheelEventArgs |
| onmousewheel | WheelEventArgs |
拖動事件
| ondrag | DragEventArgs |
| ondragend | DragEventArgs |
| ondragenter | DragEventArgs |
| ondragleave | DragEventArgs |
| ondragover | DragEventArgs |
| ondragstart | DragEventArgs |
| ondrop | DragEventArgs |
鍵盤事件
| onkeydown | KeyboardEventArgs |
| onkeyup | KeyboardEventArgs |
| onkeypress | KeyboardEventArgs |
輸入事件
| onchange | ChangeEventArgs |
| oninput | ChangeEventArgs |
| oninvalid | EventArgs |
| onreset | EventArgs |
| onselect | EventArgs |
| onselectstart | EventArgs |
| onselectionchange | EventArgs |
| onsubmit | EventArgs |
剪貼板事件
| onbeforecopy | EventArgs |
| onbeforecut | EventArgs |
| onbeforepaste | EventArgs |
| oncopy | ClipboardEventArgs |
| oncut | ClipboardEventArgs |
| onpaste | ClipboardEventArgs |
觸摸事件
| ontouchcancel | TouchEventArgs |
| ontouchend | TouchEventArgs |
| ontouchmove | TouchEventArgs |
| ontouchstart | TouchEventArgs |
| ontouchenter | TouchEventArgs |
| ontouchleave | TouchEventArgs |
指針事件
| ongotpointercapture | PointerEventArgs |
| onlostpointercapture | PointerEventArgs |
| onpointercancel | PointerEventArgs |
| onpointerdown | PointerEventArgs |
| onpointerenter | PointerEventArgs |
| onpointerleave | PointerEventArgs |
| onpointermove | PointerEventArgs |
| onpointerout | PointerEventArgs |
| onpointerover | PointerEventArgs |
| onpointerup | PointerEventArgs |
多媒體事件
| oncanplay | EventArgs |
| oncanplaythrough | EventArgs |
| oncuechange | EventArgs |
| ondurationchange | EventArgs |
| onemptied | EventArgs |
| onpause | EventArgs |
| onplay | EventArgs |
| onplaying | EventArgs |
| onratechange | EventArgs |
| onseeked | EventArgs |
| onseeking | EventArgs |
| onstalled | EventArgs |
| onstop | EventArgs |
| onsuspend | EventArgs |
| ontimeupdate | EventArgs |
| onvolumechange | EventArgs |
| onwaiting | EventArgs |
進度事件
| onloadstart | ProgressEventArgs |
| ontimeout | ProgressEventArgs |
| onabort | ProgressEventArgs |
| onload | ProgressEventArgs |
| onloadend | ProgressEventArgs |
| onprogress | ProgressEventArgs |
| onerror | ErrorEventArgs |
參考資料
[1]
源代碼: https://github.com/mrpmorris/blazor-university/tree/master/src/Components/EventCallbacks
總結(jié)
以上是生活随笔為你收集整理的Blazor University (6)组件 — 组件事件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 特斯拉为何使用.NET 技术栈?
- 下一篇: Xamarin效果第十四篇之玩耍GIS