• 深入浅出Blazor webassembly之使用State container机制实现两组件联动


    前面已经介绍了两种组件之间联动的方案, 加上这篇 State container 方案, 共三种方案, 简单总结一下:

    1 CascadingValue 组件方案, 使用简单, 但场景限制较大, 只能完成上层组件向下层组件传值。

    2. EventCallback方案,稍微复杂点, 但场景适用更多。

    3. State container 方案,功能更加强大, 代码比EventCallback方案更优美一些, 对于大型项目, 推荐使用。

    State container 就是一个blazor wasm应用注入的一个全局单例对象,因为是全局内存对象, 也很适合作为 SessionStorage 。

    State container 作为event发布者和订阅者的中介, 解耦两者关系, 实现组件联动。

    ======================================

    思路

    ======================================

    以示例说明思路:

    一个组件 ProvinceSelector 用于选择城市, 需要传值到 CitySelector 组件。

    步骤:

    1. 增加一个 AppStateContainer C#类,

        在这个类中, 定义一个 OnSelectedProvinceChange event属性, 类型为 Action, 之后事件订阅者可注入真实的 event handler。

        再定义一个 SelectedProvince 属性, 该属性的 setter 方法, 要 invoke OnSelectedProvinceChange 事件。

    ⒉ ProvinceSelector 组件, 即事件的发布者

       将要传出的信息, 封装成C#属性, 在其setter方法中, 同时更新 AppStateContainer 类的 SelectedProvince 属性, 即完成事件的发布

    3. CitySelector 组件, 即事件的订阅者

      在 OnInitialized() 方法中, 将内置的 StateHasChanged 委托实例注入到 AppStateContainer.OnSelectedProvinceChange 中, 完成订阅, 因为是将 StateHasChanged 用于响应通知, 所以 CitySelector 组件会自动完成状态更新.

       另外,  该组件需要实现 IDisposable 接口, 在 Dispose() 方法中, 要将 StateHasChanged 委托实例从 AppStateContainer.OnSelectedProvinceChange 解绑.

    ======================================

    代码

    ======================================

    AppStateContainer C#类

    //===========================
    // file: DataAppStateContainer.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类

    builder.Services.AddSingleton<AppStateContainer>();

    ProvinceSelector 组件, 事件的发布者

    @* //================================ *@
    @* // file: SharedProvinceSelector.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: SharedCitySelector.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 ;
        }
    }

    效果示意图

  • 相关阅读:
    本地缓存方式
    iOS Touch ID 身份认证
    iOS之WKWebView
    [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
    iOS利用UIDocumentInteractionController和Quick Look打开或预览文档
    轮播图的无限轮播
    贝赛尔曲线UIBezierPath(后续)
    贝赛尔曲线UIBezierPath
    NSRunLoop的进一步理解
    CADisplayLink 及定时器的使用
  • 原文地址:https://www.cnblogs.com/harrychinese/p/blazor_appstatecontainer.html
Copyright © 2020-2023  润新知