我有一组页面,它们都遵循类似的
/{report}/{id}
模式,但其中 {report} 被每个页面的具体名称替换。我们还有一个单例 reportManager
,它曾经在页面的 OnParameterSet 中更新
protected override async Task OnParametersSetAsync()
{
if (reportManager.SelectedId != id) {
reportManager.SelectedId = id;
}
var item = reportManager.SelectedItem;
}
现在此逻辑已移至每个页面使用的组件中。但是,由于页面将调用
reportManager.SelectedItem
,因此需要在页面的 OnParametersSetAsync 之前调用组件的 OnParametersSetAsync。
有什么方法可以重新排序这些东西,或者有更好的方法将该逻辑提取到某个常见的地方。
我考虑过继承,但在 blazor 组件中,如果您希望继承的组件包含派生组件,那么它有点丑陋且有点繁琐。
我还考虑过创建一些与
/{report}/{id}
匹配的页面,然后根据 {report} 参数提供正确的组件,但每次添加页面时,您都必须更新此“路由”页面。
否则我可能需要重新设计
reportManager
,因为它有点笨重
正如@topsail所说,Blazor的组件生命周期事件遵循固定的顺序,我们无法直接对它们重新排序,但您可以使用生命周期事件来实现您的要求。这是您可以尝试的代码:
ReportState.cs:
namespace ReportManagementApp.Data
{
public class ReportState
{
public string SelectedId { get; private set; }
public string SelectedItem { get; private set; }
public event Action OnChange;
public void SetSelectedId(string id)
{
if (SelectedId != id)
{
SelectedId = id;
// Fetch and set the selected item based on the ID
SelectedItem = FetchSelectedItem(id);
NotifyStateChanged();
}
}
private string FetchSelectedItem(string id)
{
// Simulate fetching an item based on the ID
return $"Item for ID: {id}";
}
private void NotifyStateChanged() => OnChange?.Invoke();
}
}
ReportStateProvider.razor:
@using ReportManagementApp.Data
<h3>ReportStateProvider</h3>
@code {
[Inject] private ReportState ReportState { get; set; } = default!;
[Parameter] public string ReportId { get; set; } = default!;
protected override async Task OnParametersSetAsync()
{
// Initialize the report state with the provided ReportId
ReportState.SetSelectedId(ReportId);
}
}
ReportPage.razor:
@page "/report/{id}"
@using ReportManagementApp.Data
@inject ReportState ReportState
<h3>Report Page</h3>
<div>
<p>Selected ID: @ReportState.SelectedId</p>
<p>Selected Item: @ReportState.SelectedItem</p>
</div>
@code {
[Parameter] public string Id { get; set; }
protected override async Task OnParametersSetAsync()
{
// This ensures that ReportState has been set before you use it
if (ReportState.SelectedId != Id)
{
ReportState.SetSelectedId(Id);
}
}
}
NavMenu.razor:
<div class="nav-item px-3">
<NavLink href="/report/1" class="nav-link" Match="NavLinkMatch.Prefix">
Report 1
</NavLink>
</div>