我们如何使用 State 容器 Blazor Webassembly 从子级调用方法

Posted

技术标签:

【中文标题】我们如何使用 State 容器 Blazor Webassembly 从子级调用方法【英文标题】:How we can call a method from child with State container Blazor Webassembly 【发布时间】:2021-11-05 04:07:36 【问题描述】:

我想从子组件调用一个方法,我有这段代码

应用状态:

public class AppState

    public string MyMessage  get; private set; 
    public string MyMsgToChildren  get; private set; 


    public event Action OnChange;

    public void SetMessage(string msg)
    
        MyMessage = msg;
        NotifyStateChanged();
    

    public void SetMessageToChildren(string msg)
    
        MyMsgToChildren = msg;
        NotifyStateChanged();
    
    private void NotifyStateChanged() => OnChange?.Invoke();

和子组件#1:

    @inject AppState AppState
<p>============================</p>
<h3>#1 Child</h3>
<p>send from Father :<b>@AppState?.MyMsgToChildren</b>  </p>

<div class="col-sm-6">
    <button @onclick="SetMessage">Send To Parent</button>

</div>
<p>============================</p>

@code 

    protected override void OnInitialized()
    
        AppState.OnChange += StateHasChanged;
    
    public void Dispose()
    
        AppState.OnChange -= StateHasChanged;
    
    void SetMessage()
    
        AppState.SetMessage("Message From Child #1");
    


#2 Child 与 #1 的代码相同 我有一个父组件:

@page "/State"

@inject AppState AppState
<p>============================</p>
<h3>Parent</h3>
<p>send from child:<b>@AppState?.MyMessage</b>  </p>
<div class="col-sm-6">
    <button @onclick="SendMsgTochildren">Send To Parent</button>
</div>
<ChildComponent></ChildComponent>
<Child2Component></Child2Component>

@code 

    public string MsgToChildren  get; private set;  = "Hi, Im your father - ";
    int i = 0;

    protected override void OnInitialized()
    
        AppState.OnChange += StateHasChanged;
    
    public void Dispose()
    
        AppState.OnChange -= StateHasChanged;
    

    void SendMsgTochildren()
    
        i++;
        AppState.SetMessageToChildren(MsgToChildren + i.ToString());
    

    /* I want to call this method from Child*/
    void TargetMethod(int page) 
     
    
    

这个应用程序运行良好,只是我想调用这个方法:“TargetMethod(int page)” 来自我的一个子组件,我还需要传递一个整数参数

我想将此代码用于分页。我尝试制作一个组件(分页)并将其添加到每个表格组件中,分页将成为主要组件的孙子,我知道我可以使用其他方式,但我更喜欢使用状态容器 在分页和其他人之间进行交流

【问题讨论】:

【参考方案1】:

添加一个 PagingEventArgs 类。

    public class PagingEventArgs : EventArgs
    
        public int Page  get; set; 
    

向您的 AppState 类添加事件和通知程序:

public event EventHandler<PagingEventArgs> PageChanged;

public void NotifyPageChanged(object sender, PagingEventArgs e)
    => PageChanged.Invoke(sender, e);

从您的分页器调用

private void Page(int page)

    appservice.NotifyPageChanged(this, new PagingEventArgs  Page = page );

并在您想要使用它的地方注册事件。

【讨论】:

【参考方案2】:

我想从我的一个中调用此方法:“TargetMethod(int page)” 子组件,我也需要传递一个整数参数

那么你可以这样尝试:

AppState.cs

 public class AppState
    
        public Action<int> OnCounterChanged  get; set;    
    

Grandparent.razor

    @inject AppState AppState;
@page "/grandparent"
<h1>Counter Value from Grandparent : @Counter</h1>
    <Parent/>


@code

    public int Counter  get; set; 

    protected override void OnInitialized()
    
        AppState.OnCounterChanged += OnCounterChanged;
    

    private void OnCounterChanged(int counter)
    
        Counter = counter;
        StateHasChanged();
    

Parent.razor

@inject AppState AppState;
<h1>Counter Value from Parent : @Counter</h1>
<Child />


@code

    public int Counter  get; set; 

    protected override void OnInitialized()
    
        AppState.OnCounterChanged += OnCounterChanged;
    

    private void OnCounterChanged(int counter)
    
        Counter = counter;
        StateHasChanged();
    

<Child />

Child.razor

@inject AppState AppState;
<h1>Counter Value from child : @Counter</h1>
<button class="btn btn-primary" @onclick="UpdateCounter"> Update Counter</button>
@code

    public int Counter  get; set; 

    private void UpdateCounter()
    
        AppState.OnCounterChanged.Invoke(++Counter);
    

我正在从子组件更新计数器并使用int 参数调用事件。 (这只是一个演示)

【讨论】:

它可以工作,但我的代码是异步代码,我有异步覆盖任务 OnInitializedAsync() 的错误 在您的 AppState 上尝试这样的操作:public Func&lt;int, Task&gt; OnCounterChanged get; set; 。对于异步方法,它应该是 Func&lt;int, Task&gt; 而不是 Action&lt;int&gt; 它不适用于我用于分页的主要代码,但对于此代码有效,我添加了另一个问题并添加了所有主要代码,谢谢 这里是问题:***.com/questions/69111539/…

以上是关于我们如何使用 State 容器 Blazor Webassembly 从子级调用方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有 Blazor Web 组件的情况下从 JavaScript 使用 C# WebAssemly

Blazor University (34)表单 —— 获得表单状态

Blazor Server App MVVM-Pattern:通过 Startup.cs 中的服务类从 App-State 的子组件更改中获取父级通知

如何将 Blazor 中的所有注册服务添加到 Simple Injector?

打开MASA Blazor的正确姿势4.3:Grid网格布局

如何使用 Blazor 上传文件?