Blazor WebAssembly 的核心就是元件,所以今天也是介紹元件的觀念。
當我們建立元件後,外部除了使用 UI 外,其實是可以存取公開成員的,只需要透過 @ref
指示詞,將 @ref
屬性新增至子元件,並且使用與子元件相同的類型來定義欄位,就可以輕鬆取得元件的公開成員了,如:
<Child @ref="Child"></Child>
@code {
private Child Child;
}
要注意元件渲染完成後才會填入子元件的實體!也就是 OnAfterRender/OnAfterRenderAsync
方法後才能夠存取其成員。
在使用子元件的方法時,如果直接這樣寫:
<button type="button" @onclick="Child.PublicFunction">Child Funtion</button>
執行時期就會直接噴錯,因為 Child
實體還沒有被填充,這時候就可以透過表達式來確保在指派事件處理常式之前,會先指派參考變數:
<button type="button" @onclick="@(()=> Child.PublicFunction())">Child Funtion</button>
倘若是透過迴圈來產生子元件,要取得所有實體可以參考此技巧:
@for (int i = 0; i < 10; i++)
{
<Child @ref="component" />
}
@code {
Child component { set => components.Add(value); }
List<Child> components = new List<Child>();
}
這樣在被填入實體時,設定的方法會轉為新增在列表中,但如果你是懶人,不想要使用這方式,這邊推薦你一個黑魔法:
@for (int i = 0; i < 10; i++)
{
<Day18SampleChild @ref="components.Add((Day18SampleChild)__value);//" />
}
@code {
List<Child> components = new List<Child>();
}
這邊的 __value
與後面的 //
我還沒搞清楚,如果之後弄懂了會再發一篇來講解,或者有路過大神再請大神幫忙講解,感謝。
以上就是存取元件實體的方法,是不是很簡單啊?
但存取元件實體這種事情,有時候是為了實現 Focus
, Click
等等事件時的目標,但這個好像並不能解決耶?
那是因為 Blazor WebAssembly 在渲染時,並不會像 Angular
(或者其他前端框架) 多包一層 component 的標籤,也就是 Blazor WebAssembly 的 Component 並不會存在於 UI 上。
那麼如果我們需要在特定事件發生時,Focus 在指定元素時,我們應該怎麼處理?
這時候一樣是透過 @ref
來取得元素實體參考,但對象不能是元件,而是 input, button 等等原生標籤,並且以 ElementReference
型別來做為參數類型:
<input @ref="inputRef" />
@code{
private ElementReference inputRef;
}
但是 ElementReference
型別只有一個 Id
成員,並不能實現上面的需求,因為這時候是需要將資訊交給 JavaScript
,由 JavaScript
來幫我們處理。
雖然開場說大話表示不用寫
JavaScript
也能寫網頁,但那種情況真的滿狹隘的,除非之後的更新處理好了這塊。
因為本篇的重點不想放太多在 JavaScript
的使用上,會在後續文章將針對JS interop詳細介紹,所以這邊將快速帶過用法。
建立 exampleJsInterop.js
檔案其內容為:
window.exampleJsFunctions = {
focusElement: function (element) {
element.focus();
}
}
記得在 index.html
中引用:
<script src="../js/exampleJsInterop.js"></script>
然後回到我們的元件來,只需要注入 IJSRuntime
並使用其 InvokeVoidAsync
方法就可以使用剛剛撰寫的 JS
方法了。
@inject IJSRuntime JSRuntime
@code {
public async Task SetFocus()
{
await JSRuntime.InvokeVoidAsync(
"exampleJsFunctions.focusElement", InputRef);
}
}
只要呼叫 SetFocus
方法,就能夠正確 focus 在 input 上了,這樣了解了嗎?
以上就是元件參考的取得方法了,是不是很簡單呀?一樣有我寫的範例程式碼 - day18。
感謝大家的閱讀,我們明天見。
參考資料
捕獲元件的參考
Capture references to multiple similar child-components #13358