Blazor组件未在状态更改上调用OnInitializedAsync,链接数据获取

问题描述

我是新手,仍然在学习,并且仪表板存在状态问题。

我有一个获取仪表板和面板的组件:

@if (Data == null)
{
    <Loader></Loader>
    return;
}
<Row NoGutters="true">
    @foreach (var panel in Data.Panels)
    {
        <Column XS="12" SM="12" MD="6" LG="6" XL="4" Class="mb-4">
            <CascadingValue Value="@panel.Id">
                <DashboardMatare DateHeader="@panel.DateHeader" Header="@panel.Header" ></DashboardMatare>
            </CascadingValue>
        </Column>
    }
</Row>

它通过OnParameteRSSetAsync来获取数据并正常工作,它会获取新面板并进行渲染

但是当我交换到另一个仪表盘时,“ DashboardMatareChartJs”的先前仪表盘的值仍然存在。

如果各面板之间的面板数量不同,它将渲染新面板。

我将panelId串联到孩子上,这样blazor会明白需要改变状态。

DashboardMatare:

<DashboardContainer>

<DashboardHeader Header="@Header" DateHeader="@DateHeader"></DashboardHeader>

<CascadingValue Value=PanelId>
    <DashboardMatareChartJs />
</CascadingValue>

DashboardMatareChartJs:

if (Data == null)
{
    <Loader />
    return;
}

<div class="pl-3">
    <Row NoGutters="true" Class="h-75">
        <Column Class="col-12">
            <div class="matare">
                <div class="valueWrapper">
                    <canvas class="metergraph" ref="ReferencetochartJs">
                    </canvas>
                </div>
            </div>
        </Column>
    </Row>
    <Row>
        <Column Class="text-left col-12">
            <DashboardJamforMed JamforMedText="Data.JamforMedText" IsProcent="Data.ShowPercentage"></DashboardJamforMed>
        </Column>
    </Row>
</div>


[Inject]
protected HttpClient HttpClient { get; set; }

[CascadingParameter]
public Guid PanelId { get; set; }

public ElementReference ReferencetochartJs { get; set; }

[Inject]
private IJSRuntime JsRuntime { get; set; }

public DashboardPanelGraphDataDto Data { get; set; }

protected override async Task OnInitializedAsync()
{
    Data = await HttpClient.GetFromJsonAsync<DashboardPanelGraphDataDto>($"api/DashboardBlazor/GetChartData/{PanelId}");
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (Data == null || ReferencetochartJs.Context == null)
    {
        return;
    }

    await JsRuntime.InvokeVoidAsync("chartService.drawGraph",ReferencetochartJs,Data.ChartData,Data.TypeOfGraph,Data.ShowPercentage);
}

DashboardHeader将始终具有正确的数据

问题似乎是在更改PanelId时组件不会调用OnInitializedAsync。我认为这是一个结构性问题,因为我尝试通过@ref强制statehaschanged并从父级调用StateHasChanged,仍然无法正常工作。

如果我通过“ DashboardMatareChartJs”上的OnParameteRSSetAsync提取数据,则它将加载新数据,但是它将多次加载,并且对于尚不在查看中的面板。我意识到这意味着我可能还不了解100%火焰的生命周期,因此希望有人可以将我推向正确的方向。

谢谢!

解决方法

尝试使用@key指令属性来强制Blazor重建DashboardMatare对象,如下所示:

<DashboardMatare @key="@panel.Id" DateHeader="@panel.DateHeader" Header="@panel.Header" ></DashboardMatare>

此答案基于以下内容:

还可以使用@key防止Blazor在对象更改时保留元素或组件子树:

<div @key="currentPerson">
    ... content that depends on currentPerson ...
</div>

如果@currentPerson更改,则@key属性指令将强制Blazor丢弃整个及其后代,并使用新的元素和组件在UI中重建子树。如果您需要保证@currentPerson更改时不保留任何UI状态,这将很有用。

Link to Source...