今天要來介紹的是狀態管理,透過狀態管理可以使每個元件都能夠取得一致的狀態,也能透過此方式來進行參數傳遞,加上之前介紹的元件傳值技巧,魔術技巧 - 父子溝通問題與魔術技巧 - 傳值技巧,這就是目前 Blazor WebAssembly 元件傳值的三種技巧。
還記得相依性注入魔術技巧內容吧?我們可以放任意服務實體進 DI Container 中,而以 Singleton
為生命週期的服務,可以確保每個需要此服務的元件都得到相同實體,所以我們也可以將資料模型當成服務注入,來進行元件間的傳值。
首先建立一個資料模型:
1 2 3 4 5
| public class Day23SampleModel { public string Value { get; set; } }
|
然後將該服務新增到 DI:
1 2
| builder.Services.AddSingleton<Day23SampleModel>();
|
如此一來我們就可以使用 @inject Day23SampleModel Day23SampleModel
來從 di container 中取得同一個 Day23SampleModel
實體如:
1 2 3 4 5 6 7
| @* Day23Sample.razor *@ @inject Day23SampleModel Day23SampleModel
<p> Day23SampleModel.Value: @Day23SampleModel.Value </p> <input @bind="Day23SampleModel.Value" />
|
1 2 3 4 5 6 7
| @* Day23Sample2.razor *@ @inject Day23SampleModel Day23SampleModel
<p> Day23SampleModel.Value: @Day23SampleModel.Value </p> <input @bind="Day23SampleModel.Value" />
|
當任何一個元件修改了 Day23SampleModel.Value
的值,另一個元件也會被修改。
以上就是 .NET 元件狀態管理也是傳值的第三種方式。
但此種狀態管理方式是寫在記憶體中,若想要保留在瀏覽器上,則可以考慮使用 JavaScript 來操作 localStorage
和 sessionStorage
集合:
localStorage
:範圍設定為瀏覽器的視窗,如果使用者重載或關閉頁面甚至重新開啟瀏覽器,狀態都會持續存在,且當使用者開啟多個瀏覽器索引標籤,會在索引標籤之間共用狀態,直到明確清除為止,資料會持續存在。
sessionStorage
:範圍設定為瀏覽器索引標籤,如果使用者重載此索引標籤,狀態會持續存在,直到使用者關閉索引標籤或瀏覽器,狀態就會遺失,而且如果使用者開啟多個瀏覽器索引標籤,每個索引標籤都有自己獨立的資料版本。
以 localStorage
來做練習,我們可以撰寫一個 JavaScript 方法如:
1 2 3 4 5 6 7 8
| window.exampleJsFunctions = { setLocalStorageItem: function (key, value) { localStorage.setItem(key, value); }, getLocalStorageItem: function (key) { return localStorage.getItem(key); } };
|
並在初始化時,從 localStorage
取得對應的值,並提供儲存按鈕來更新 localStorage
的內容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| <p> LocalStorage: @localStorageValue </p> <input @bind="localStorageValue" /> <button @onclick="Save">Save</button>
@code { private string localStorageValue;
protected override async Task OnInitializedAsync() { localStorageValue = await GetLocalStorageItem("test"); await base.OnInitializedAsync(); }
public async Task Save() { await SetLocalStorageItem("test", this.localStorageValue); }
public async Task SetLocalStorageItem(string key, string value) { await JSRuntime.InvokeVoidAsync("exampleJsFunctions.setLocalStorageItem", key, value); }
public async Task<string> GetLocalStorageItem(string key) { return await JSRuntime.InvokeAsync<string>("exampleJsFunctions.getLocalStorageItem", key); } }
|
當然也可以將存取 localStorage
的方法抽成服務,這樣以後有元件需要使用 localStorage
就可以直接注入服務啦。
以上就是狀態管理的方法,若想要參考完整程式碼可以到範本程式碼 - Day23看看唷。
感謝大家的閱讀,我們明天見。
參考資料
ASP.NET Core Blazor 狀態管理