我有一个带有路线
@page "/observation/{Id:int}"
的页面。该页面还包含上一个/下一个导航链接,以便用户可以在观察之间快速切换。当我单击链接时,浏览器中的路线会更新,但页面不会重新加载。我想将它们保留为超链接,以便用户可以在新选项卡中打开,所以我认为单击时使用 NavigateTo
不适用于我。如何让页面重新加载,同时仍允许用户在新选项卡中打开链接?
当您
Navigate
到达同一页面时,您并没有重新加载组件,只是重新渲染它。 OnInitialized{Async}
未被调用。 OnParametersSet{Async}
是。
此页面演示了如何处理此问题:
@page "/"
@page "/Index/{Id:int}"
@inject NavigationManager NavManager
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
<div>
<button class="btn btn-dark" @onclick=Previous>Previous</button>
<button class="btn btn-dark" @onclick=Next>Next</button>
</div>
<div class="alert alert-primary m-2">@(_selectedData?.Name ?? "No Data Exists")</div>
@code {
[Parameter] public int Id { get; set; } = 1;
private Data? _selectedData;
protected override async Task OnParametersSetAsync()
{
if (this.Id != _selectedData?.Id)
{
await Task.Delay(100);
_selectedData = _myData.FirstOrDefault(item => item.Id == this.Id);
}
}
private void Next()
{
this.NavManager.NavigateTo($"/index/{this.Id + 1}");
}
private void Previous()
{
this.NavManager.NavigateTo($"/index/{this.Id - 1}");
}
private List<Data> _myData = new()
{
new(1, "UK"),
new(2, "France"),
new(3, "Spain"),
new(4, "Portugal"),
};
public record Data(int Id, string Name);
}
我不太喜欢这个答案,因为它会导致页面硬刷新,但我会通过在
NavigateTo
时执行
OnLocationChanged
来完成我需要的操作
[Inject] NavigationManager Navigator { get; set; }
protected override async Task OnInitializedAsync()
{
Navigator.LocationChanged += OnLocationChanged;
}
private async void OnLocationChanged(object sender, LocationChangedEventArgs e)
{
Navigator.NavigateTo(e.Location, true);
}
我是这样做的: Blazor 页面具有路由 @page“/details/{id:Guid}”。在OnLocationChanging中,如果相对目标url以当前url开头,我们尝试从url中解析新的Id并加载新内容。
protected override async Task OnInitializedAsync()
{
NavigationManager.RegisterLocationChangingHandler(OnLocationChanging);
}
private async ValueTask OnLocationChanging(LocationChangingContext context)
{
var segments = (new Uri(context.TargetLocation)).Segments.Where(s => s != "/").ToList();
if (segments.FirstOrDefault()?.StartsWith("details", StringComparison.OrdinalIgnoreCase) == true)
{
if (Guid.TryParse(segments.LastOrDefault(), out var id))
{
await LoadDetails(faqId);
}
}
}