我是新手,仍然在学习,并且仪表板存在状态问题。
我有一个可获取仪表板和面板的组件:
@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%火焰的生命周期,因此希望有人可以将我推向正确的方向。
谢谢!
答案 0 :(得分:1)
尝试使用@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状态,这将很有用。