我有类似于以下的代码:
@page "/somepage/{Id:guid}/add"
@page "/somepage/{Id:guid}/remove"
@inject NavigationManager navigationManager
@implements IAsyncDisposable
if ( @remove ) {
<div>Remove!</div>
} else {
<div>Add!</div>
}
@code{
[Parameter]
public Guid Id { get; set; }
protected override void OnInitialized()
{
navigationManager.LocationChanged += HandleLocationChanged;
}
public async ValueTask DisposeAsync()
{
navigationManager.LocationChanged -= HandleLocationChanged;
}
protected override async Task OnParametersSetAsync()
{
remove = navigationManager.Uri.Contains("remove");
// Load some data...
await base.OnParametersSetAsync();
}
private void HandleLocationChanged(object? sender, LocationChangedEventArgs e)
{
var pageUris = new[] {
$"/somepage/{Id}/add",
$"/somepage/{Id}/remove"
};
var uri = navigationManager.Uri.Replace( navigationManager.BaseUri, "" );
if ( !pageUris.Contains(uri) ) return;
remove = navigationManager.Uri.Contains("remove");
// Load some data...
StateHasChanged();
}
}
在HandleLocationChanged
事件中,我意识到,如果用户单击指向完全不同页面的链接,那么数据将加载到错误的页面。所以我添加了一个警卫来检查NavigationManager.Uri
,看看它是否指向不同的位置。
有没有办法让它更通用?例如,我可以获得特定页面的路线列表,然后在比较中使用它吗?
您的问题询问如何替换硬编码的pageUris
变量:
var pageUris = new[] {
$"{navigationManager.BaseUri}somepage/add",
$"{navigationManager.BaseUri}somepage/remove"
};
知道@page "/foo"
会导致[RouteAttribute("foo")]
应用于页面生成的类,创建一个函数来替换代码是很简单的:
private string[] GetPageUrls()
{
return GetType().GetCustomAttributes<RouteAttribute>().Select(x => x.Template).ToArray();
}
这将为您拥有的每个@page
指令生成一个元素,其中包含以下值:
"/somepage/add", "/somepage/remove"
在你的问题中,你将它与navigationManager.BaseUri
结合在一起,我认为这应该是不必要的,因为默认情况下,Blazor应用程序会设置基本url(即<base href="/" />
(,但如果你想返回该url,那么将GetPageUrls
更改为包含该url显然是微不足道的。
最后,如果您想在其他地方使用它,那么将它转换为扩展方法应该很简单。