假如我們想增加的按鈕用來清除form的資料,最快的方式是增加一個type=”reset”的按鈕,這時候就用到兩個按鈕了,可以用到Blazor的核心觀念:Component抽離。
我們先在Shared資料夾新增一個Razor元件名為MyButton,定義3個變數分別代表按鈕類型、按鈕樣式、按鈕名稱,注意要在屬性上面加上[Parameter],這是告訴Blazor這邊的值會來自叫用這個Component的上層Component。
接著移除標題的單向綁定,再將更新時間的div移到<EditForm>外面,因為reset按鈕會清除整個form,我們不希望更新時間也被清除。最後在最下面使用兩個<MyButton>Component,再輸入我們要的按鈕類型、按鈕樣式、按鈕名稱,這邊Blazor會告訴你還有哪些Parameter沒有被呼叫,如果有重複的Parameter也會有提示,所以不用擔心。
按下Reset按鈕,可以看到標題跟內容都被清除了。
要注意的是Parameter不支援混合razor及html字串的寫法,如果想這麼做建議用field、property或是string方法回傳組合好的字串。

Parameter還有一點要避免,當Parent Component傳值到Child Component時,Parent Component若有StateHasChanged相關動作,會將Parent Component及Child Component重新render,除非在Child Component用一個變數先接起來Parent Component傳來的值。
上面的文字似乎有看沒有懂,我們來看微軟給的例子,先建立一個ExpanderComponent,裡面做的事情很簡單,只要點擊<div>就會收合或是展開內容。還有一個型別為RenderFragment的ChildContent,這是讓呼叫該Component的外部Component決定內容樣板。
接著在Post.razor叫用兩個Expander,第一個有用到ChildContent並放入<p>元素,最後看到一個button帶有@onclick="StateHasChanged"的事件,模擬Parent Component的StateHasChanged事件。
打開網頁可以看到兩個Expander的Expanded皆為True
接著兩個Expander都點一下,可以看到Expanded都變False了
不過如果這時候點底下的button,會發現只有上面的Expanded變成True,這是為什麼?
原因就在於Parent的state跟ChildContent這個屬性,因為Parent的state改變了會重新render並將新資料傳給第一個Child,所以Expanded被重設為true,第二個Child因為沒有接收ChildContent所以不會重新render。
為了避免這問題,可以定義一個私有field名為expanded,當Component初始化時接下Parent傳來的Expanded,之後的邏輯都根據expanded處理。
Ref: Component parameters
Ref: ComponentBase.StateHasChanged Method