深入淺出Blazor webassembly之使用State container機(jī)制實(shí)現(xiàn)兩組件聯(lián)動(dòng)
前面已經(jīng)介紹了兩種組件之間聯(lián)動(dòng)的方案, 加上這篇 State container 方案, 共三種方案, 簡(jiǎn)單總結(jié)一下:
1 CascadingValue 組件方案, 使用簡(jiǎn)單, 但場(chǎng)景限制較大, 只能完成上層組件向下層組件傳值。
2. EventCallback方案,稍微復(fù)雜點(diǎn), 但場(chǎng)景適用更多。
3. State container 方案,功能更加強(qiáng)大, 代碼比EventCallback方案更優(yōu)美一些, 對(duì)于大型項(xiàng)目, 推薦使用。
State container 就是一個(gè)blazor wasm應(yīng)用注入的一個(gè)全局單例對(duì)象,因?yàn)槭侨謨?nèi)存對(duì)象, 也很適合作為 SessionStorage 。
State container 作為event發(fā)布者和訂閱者的中介, 解耦兩者關(guān)系, 實(shí)現(xiàn)組件聯(lián)動(dòng)。
======================================
思路
======================================
以示例說(shuō)明思路:
一個(gè)組件 ProvinceSelector 用于輸入省份, 該省份需要傳值到 CitySelector 組件, 以便聯(lián)動(dòng)City 的選擇.
步驟:
1. 增加一個(gè) AppStateContainer C#類(lèi),
在這個(gè)類(lèi)中, 定義一個(gè) OnSelectedProvinceChange event屬性, 類(lèi)型為 Action, 之后事件訂閱者可注入真實(shí)的 event handler。
再定義一個(gè) SelectedProvince 屬性, 該屬性的 setter 方法, 要 invoke OnSelectedProvinceChange 事件。
⒉ ProvinceSelector 組件, 即事件的發(fā)布者
將要傳出的信息, 封裝成C#屬性, 在其setter方法中, 同時(shí)更新 AppStateContainer 類(lèi)的 SelectedProvince 屬性, 即完成事件的發(fā)布
3. CitySelector 組件, 即事件的訂閱者
在 OnInitialized() 方法中, 將內(nèi)置的 StateHasChanged 委托實(shí)例注入到 AppStateContainer.OnSelectedProvinceChange 中, 完成訂閱, 因?yàn)槭菍?StateHasChanged 用于響應(yīng)通知, 所以 CitySelector 組件會(huì)自動(dòng)完成狀態(tài)更新.
另外, 該組件需要實(shí)現(xiàn) IDisposable 接口, 在 Dispose() 方法中, 要將 StateHasChanged 委托實(shí)例從 AppStateContainer.OnSelectedProvinceChange 解綁.
======================================
代碼
======================================
AppStateContainer C#類(lèi)
//=========================== // file: Data\AppStateContainer.cs //=========================== using System ; namespace blazorDemo1.Data { public class AppStateContainer { private string selectedProvince ; public string SelectedProvince{ get {return selectedProvince;} set{SetSelectedProvince(value);} } public event Action OnSelectedProvinceChange; public void SetSelectedProvince(string value){ selectedProvince=value ; OnSelectedProvinceChange?.Invoke(); } } }
program.cs DI 框架注入 AppStateContainer類(lèi)
builder.Services.AddSingleton<AppStateContainer>();
ProvinceSelector 組件, 事件的發(fā)布者
@* //================================ *@ @* // file: Shared\ProvinceSelector.razor *@ @* //================================= *@ @using blazorDemo1.Data @inject AppStateContainer AppStateContainer <h2> Province Selector Component </h2> <input type="text" class="text" @bind="Province" @bind:event="oninput"> @code{ private string province ; public string Province{ get => province; set{ province=value ; AppStateContainer.SelectedProvince=province ; } } }
CitySelector 組件, 事件的訂閱者
@* //================================ *@ @* // file: Shared\CitySelector.razor *@ @* //================================= *@ @page "/city" @using blazorDemo1.Data @inject AppStateContainer AppStateContainer @implements IDisposable <h1> City Selector Component</h1> <p> You have selected the province: @AppStateContainer.SelectedProvince </p> <ProvinceSelector></ProvinceSelector> @code{ protected override void OnInitialized(){ AppStateContainer.OnSelectedProvinceChange+=StateHasChanged ; } public void Dispose(){ AppStateContainer.OnSelectedProvinceChange-=StateHasChanged ; } }
效果示意圖


浙公網(wǎng)安備 33010602011771號(hào)