首页 > 解决方案 > 使用事件时 Blazor 状态未在子组件之间更新

问题描述

我在 Blazor wasm 应用程序中有两个独立的组件,我试图在它们之间进行通信。在某些情况下,通信失败,我不明白为什么。

(简化的)设置如下

<ParentComponent>
    <HeaderComponent>
        <ProgressBar IsLoading="<Set by IsLoading property from header>" />
    </HeaderComponent>
    <ResultContainer />
</ParentComponent>

后面的代码如下所示:

public class ResultContainerStateManager
{
    public event Action OnLoadStart;

    public event Action OnLoadFinish;

    public NotifyLoadStart() => this.OnLoadStart?.Invoke();

    public NotifyLoadFinish() => this.OnLoadFinish?.Invoke();
}

public partial class HeaderComponent
{
    [Inject]
    public ResultContainerStateManager ResultContainerStateManager { get; set; }

    private bool IsLoading { get; set; }

    protected override void OnInitialized()
    {
          this.ResultContainerStateManager.OnLoadStart += () => this.IsLoading = true;

          this.ResultContainerStateManager.OnLoadFinish += () => this.IsLoading = false;

          base.OnInitializer();
    }
}

public partial class ResultContainer
{
    [Inject]
    public ResultContainerStateManager ResultContainerStateManager { get; set; }

    private bool IsLoading { get; set; }

    protected override async Task OnParametersSetAsync()
    {
          <code>

          if (shouldLoadData)
          {
               this.ResultContainerStateManager.NotifyLoadStart();

               <more code>

               this.ResultContainerStateManager.NotifyLoadFinish();
          }

          await base.OnParametersSetAsync();
    }
}

public partial class ProgressBar
{
     [Parameter]
     public bool IsLoading { get; set; }
}

进度条中的IsLoading参数是从IsLoading属性中设置的HeaderComponent,例如

<div id="headerComponent">
    
    <More html here>

    <ProgressBar IsLoading="@this.IsLoading" />
</div>

我认为这并不重要,但进度条本身使用该MatProgress组件,如下所示:

@if (this.IsLoading)
{
    <MatProgress Indeterminate="true" />
}
else 
{
    <Other html code>
}

问题是进度条在ResultContainer执行NotifyLoadStart()方法时开始,但在执行方法时并没有停止NotifyLoadFinish()。我可以在调试时看到调用后的IsLoading属性HeaderComponent设置回false NotifyLoadFinish(),但它对UI没有影响。

到目前为止我已经尝试过:

这些都没有改变任何东西,我真的很想知道为什么。

我唯一的成功是使用EventCallbacks而不是事件。但我在许多其他地方使用事件,它们似乎都工作正常。

有人可以告诉我为什么事件似乎失败了,以及如何解决这个问题?

标签: .net-coreblazorblazor-webassembly

解决方案


试试这个代码

 public async Task OnLoadStart()
    {
        this.IsLoading = true;
        await InvokeAsync(() => { StateHasChanged(); });
    }



 public async Task OnLoadFinish()
    {
        this.IsLoading = false; 
        await InvokeAsync(() => { StateHasChanged(); });
    }

protected override void OnInitialized()
{
     this.ResultContainerStateManager.OnLoadStart += OnLoadStart;
     this.ResultContainerStateManager.OnLoadFinish += OnLoadFinish;
 }

改变 :public event Action OnLoadStart;

到: public event Func<Task> OnLoadStart;

和: public event Action OnLoadFinish;

TP: public event Func<Task> OnLoadFinish;

在 HeaderComponent 组件中实现 IDisposable:

@implements IDisposable

public void Dispose()
{
    this.ResultContainerStateManager.OnLoadStart -= OnLoadStart;
    this.ResultContainerStateManager.OnLoadFinish -= OnLoadFinish;
}

尽可能开始异步编码。


推荐阅读