我有一个服务,其中包含项目目录。这些项目依赖于该服务的活动公司。
在Service中,我刷新目录并触发一个事件。
在上述布局中的父组件中,我捕获了该事件。
我期望这将导致CatalogSectionA和CatalogSectionB组件刷新。
目录区域A
我原本期望在父组件中调用StateHasChanged()会强制重新渲染 CatalogSectionA 和 CatalogSectionB,但它们没有重新渲染。
我可以在每个组件上添加一个 Refresh 方法,在父级处理 company 变更事件时调用那些方法,但我认为在 Blazor 中不需要这样做,StateHasChanged() 应该就可以解决问题?
// Tell Service to refresh in context of Company 1
await Service.SetActiveCompany(1);
// Get Catalog (which will be in the context of Company 1)
Catalog catalog = Service.Catalog;
// Tell Service to refresh in context of Company 2
await Service.SetActiveCompany(2);
// Get Catalog (which will be in the context of Company 2)
catalog = Service.Catalog;
这段代码在独立环境下运行正常,目录会根据所选公司刷新展示的物品。
在我的应用程序中,我有一个布局包含下拉菜单,用于选择活动公司。当这个选项改变时,我会调用:
await Service.SetActiveCompany(dropdown.selectedCompanyId);
在Service中,我刷新目录并触发一个事件。
public class CompanyChangedEventArgs : EventArgs { }
public class Service
{
public event EventHandle<CompanyChangedEventArgs> CompanyChanged;
protected void OnCompanyChanged()
=> CompanyChanged?.Invoke(this, new CompanyChangedEventArgs());
public Catalog Catalog { get; private set; }
public async Task SetActiveCompany(int companyId)
{
Catalog = await API.GetCatalogForCompany(companyId);
OnCompanyChanged();
}
}
在上述布局中的父组件中,我捕获了该事件。
<CatalogSectionA />
<CatalogSectionB />
@code {
protected override void OnInitialized()
{
Service.CompanyChanged += HandleCompanyChanged;
base.OnInitialized();
}
HandleCompanyChanged(object sender, EventArgs e) => StateHasChanged();
}
我期望这将导致CatalogSectionA和CatalogSectionB组件刷新。
目录区域A
<div>
@foreach (Item i in Catalog.SectionA.Items)
{
<div>@i.Name</div>
}
</div>
@code {
Catalog Catalog => Service.Catalog;
}
目录部分B
<div>
@foreach (Item i in Catalog.SectionB.Items)
{
<div>@i.Name</div>
}
</div>
@code {
Catalog Catalog => Service.Catalog;
}
我原本期望在父组件中调用StateHasChanged()会强制重新渲染 CatalogSectionA 和 CatalogSectionB,但它们没有重新渲染。
我可以在每个组件上添加一个 Refresh 方法,在父级处理 company 变更事件时调用那些方法,但我认为在 Blazor 中不需要这样做,StateHasChanged() 应该就可以解决问题?
InvokeAsync
中调用StateHasChanged
吗?例如:HandleCompanyChanged(…) => InvokeAsync(() => StateHasChanged())
- pokeStateHasChanged
不会导致子组件重新渲染。那样会很昂贵。更改后的状态只适用于当前组件,因此该组件将检查是否需要重新渲染任何内容。由于子组件从外部看仍然是相同的(未更改任何参数或其他内容),因此父组件不会导致子组件重新渲染。 - 我建议您将“Catalog”作为参数传递给子组件。这使数据流更明确,并解决了您的问题。 - poke