畫面元件與我們的模型物件該如何綁定,才能在使用者更改欄位內容時,同步修改模型物件的對應屬性?並且當使用者操作畫面元件時,如何捕捉元件發出的事件?今天要帶大家認識的是資料繫結與事件處理,透過這兩種處理來能讓表單正確的與使用者互動。
透過 @bind
指示詞屬性來將指定的欄位、屬性或 razor
的運算式值繫結到 HTML 元素屬性上,使用方式為:
<input @bind="currentValue" />
@code {
private string currentValue;
}
當元素失去焦點時,就會自動更新欄位值,因為透過 @bind
來繫結時,會將表達式的當前值 currentValue
與 HTML value
屬性關聯,並使用已註冊的事件處理來修改內容,也就等同於以下:
<input value="@currentValue"
@onchange="@((ChangeEventArgs __e) => currentValue = __e.Value.ToString())" />
@code {
private string currentValue;
}
所以只有當 onchange
事件觸發時,才會變更欄位值,但如果想要增加事件,可以使用 @bind:event
來增加變更的時間點:
<input @bind="currentValue" @bind:event="oninput" />
@code {
private string currentValue;
}
這樣一來也會同時註冊預設的 oninput
事件處理,但如果預設的事件不能滿足你的需求,那麼就需要自己來撰寫事件處理了。
但你可能會發現昨天使用的範例程式碼並不是使用 @bind
來綁定屬性,而是 @bind-Value
來綁定這又是為什麼?那是因為昨天使用的元件是內建輸入元件而不是原生的 input 元件,所以我們綁定的對象是子元件的 Value
屬性,針對父子傳值這部分將會在介紹客製化元件時再詳細說明,這邊有個概念就好。
透過 @on{Event}
指示詞屬性來綁定 HTML 元素的事件,像是點擊、輸入等等,以點擊事件為範例為:
<button class="btn btn-primary" @onclick="SayHello">
Say hello
</button>
@code {
private void SayHello(MouseEventArgs e)
{
Console.WriteLine("Hello!");
}
}
點擊時會在 Console
視窗上輸出 Hello
,事件處理也可以是非同步的且傳回 Task
,只需要調整事件處理的方法就好如:
private async Task SayHello(MouseEventArgs e)
{
Console.WriteLine("Hello!");
}
而方法參數型別為 MouseEventArgs
,屬於事件引數類型,每一種事件都能對應到特定的類型,因為真的太多了,這邊就不列舉,請自行到事件引數類型觀看。
在處理事件時,往往都會需要特定資料,以 MouseEventArgs
為例,就提供了事件當下
alt
, ctrl
與 shift
鍵等等資訊,以方便針對每一種情境下的處理邏輯。
而除了透過方法來綁定外,也可以使用 lambda 運算式:
<button @onclick="@(e => Console.WriteLine("Hello, world!"))">Say hello</button>
使用時也跟第七天的建議一樣,用 foreach
來取代 for
,避免在 lambda 運算式中使用迴圈變數,否則會導致所有的 lambda 使用了相同的值,但如果堅持使用 for,可以將迴圈變數指派給區域變數以避免此問題。
最後,講到 HTML 事件處理,就不能缺少兩個阻擋行為:
防止預設動作:透過 @on{EVENT}:preventDefault
指示詞屬性可以防止預設動作。因為除了你自己寫的事件處理,元素也有自己的預設動作,當預設動作會影響我們的業務邏輯時,這就派上用場了。
停止事件傳播:透過 on{Event}:stopPropagation
指示詞屬性可以停止事件傳播。因為 HTML 元素具有事件冒泡機制,簡單說就是當你觸發子層某事件時,父層相同事件也會被觸發,而導致預期外的事件產生,就能使用它來避免了。
以上就是元件的資料繫結與事件處理。
感謝大家的閱讀,我們明天見。