.net core 使用事件时,Blazor状态在子组件之间不更新

.net core 使用事件时,Blazor状态在子组件之间不更新,.net-core,blazor,blazor-webassembly,.net Core,Blazor,Blazor Webassembly,我在Blazor wasm应用程序中有两个独立的组件,我正试图在这两个组件之间进行通信。在某些情况下,沟通失败,我无法理解原因 简化的设置如下所示 <ParentComponent> <HeaderComponent> <ProgressBar IsLoading="<Set by IsLoading property from header>" /> </HeaderComponent&g

我在Blazor wasm应用程序中有两个独立的组件,我正试图在这两个组件之间进行通信。在某些情况下,沟通失败,我无法理解原因

简化的设置如下所示

<ParentComponent>
    <HeaderComponent>
        <ProgressBar IsLoading="<Set by IsLoading property from header>" />
    </HeaderComponent>
    <ResultContainer />
</ParentComponent>
我认为这无关紧要,但进度条本身使用MatProgress组件,如下所示:

@if (this.IsLoading)
{
    <MatProgress Indeterminate="true" />
}
else 
{
    <Other html code>
}
问题在于,进度条在ResultContainer执行NotifyLoadStart方法时启动,但在执行NotifyLoadFinish方法时不会停止。 我可以在调试时看到,在NotifyLoadFinish调用之后,HeaderComponent的IsLoading属性被设置回false,但它对UI没有影响

到目前为止,我所尝试的:

将ResultContainerStateManager直接注入进度栏 我已经尝试过将环境更改为Func并异步处理 我已尝试添加等待任务。在每次通知呼叫后进行屈服 我已经尝试在事件处理程序中添加this.StateHasChanged调用,并且在每次通知调用之后,我知道后者不应该更改任何内容,因为它不在同一层次结构中 所有这些都没有改变任何事情,我真的想知道为什么

我唯一的成功就是使用EventCallbacks而不是events。但我在很多其他地方使用事件,它们似乎都很好

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

试试这段代码

 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;
 }
更改:公共事件操作OnLoadStart

To:公共事件函数OnLoadStart

和:公共事件行动完成

Tp:公共事件函数OnLoadFinish

在HeaderComponent组件中实现IDisposable:

@implements IDisposable

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

尽可能异步地开始编码。

ProgressBar组件的参数IsLoading的值在其他哪个组件中定义?哪个组件拥有它?它是ParentComponent、HeaderComponent还是页面?@只是Benn它不在HeaderComponent中。标头将其自己的IsLoading属性传递到ProgressBar中。我会修改代码让它更清晰。我想base.OnInitializer是一个输入错误?这很有效,谢谢。这是额外的this.state在OnLoadFinish中发生的变化造成的差异。但是在OnLoadStart方法中我不需要它。。。我想知道为什么。以及为什么在使用EventCallbacks时,它可以在没有任何StateHasChanged调用的情况下完美工作。整个事情真的很难看。两者的原因都隐藏在组件的生命周期中。OnParametersSetAsync方法在命中第一个等待时继续渲染。我的猜测是,在任何等待之前调用NotifyLoadStart方法?因此,进度条按预期呈现。但是,完成是稍后完成的,所以您需要调用StateHasChanged来触发重新加载程序。另一方面,EventCallback是blazor公民的第一部分。当它们完成操作时,触发器状态会自行更改。使用事件操作可以。我已经修改了它,请查看我对event Func的回答,以便使用异步。Action是一个委托,在Blazor的早期,我们经常在UI事件处理程序中使用它。目前,我们从中受益,并使用EventCallback结构。请注意,EventCallback不是委托。Action是委托,Func是委托,但不是专门为Blazor创建的EventCallback。EventCallback类型提供了要使用的适当委托。它特别确定并设置目标,这是Action委托的一个属性,最重要的是它自动调用StateHasCahnged方法。
 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;
 }
@implements IDisposable

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