我需要更新Blazor页面,以便在查询字符串更改时进行更新



我有一个名为NavBar.razor的Blazor组件,它显示一个带有标签列表的Radzen导航菜单。当用户单击标记(RadzenPanelMenuItem(时,组件OrderBrowser.razor将加载到菜单旁边的页面中。查询字符串让OrderBrowser.razor知道选择了什么标记。(请参阅下面的OnInitializedAsync方法。(该组件将关联的订单加载到网格中。

当用户第一次单击某个标记时,这种方法运行良好,但当用户单击其他标记时,即使uri发生了更改,OnInitializedAsync方法也不会执行。因此,我添加了一个事件处理程序,以便在uri更改时强制重新加载。这是有效的,但由于某种原因,它似乎重新加载了两次,导致第二次重新加载时出现不希望的闪烁。

有人知道更好的方法吗?谢谢

NavBar.razor:中的代码

@foreach (var item in TagsAndCounts)
{
<Radzen.Blazor.RadzenPanelMenuItem 
Text="@(item.Tag + " (" + item.Count + ")")"
Path="@("orders/browse?tag=" + item.Tag)" />
}

OrderBrowser.razor:中的订单网格

<OrderGrid Data="@orders" AllowPaging="false" />

OrderBrowser.razor中的代码:

protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
NavManager.LocationChanged += NavManager_LocationChanged;
var uri = NavManager.ToAbsoluteUri(NavManager.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("tag", out var tag))
{
orders = await orderService.GetOrdersForTagAsync(tag);
}
}
private void NavManager_LocationChanged(object sender, LocationChangedEventArgs e)
{
NavManager.NavigateTo(NavManager.Uri, forceLoad: true);
}

使用此事件

[Parameter]
[SupplyParameterFromQuery]
public string? Page { get; set; } = "0";
protected override void OnParametersSet()
{
//Fire your Code her
}

当您从:yourUrl/tag/tagname1转到并单击链接yourUrl/tag/tagname2时,它不会激发OnInitializedAsync,因为没有创建新页面。这是有意的、正确的行为。但有点令人困惑。

通过引入.net6,您可以利用SupplyFromQueryParameter属性的新功能,该功能将根据查询字符串更改其值。

[Parameter, SupplyParameterFromQuery(Name = "tag")] public string Tag { get; set; } = "";

现在,您可以在Tag属性的seeter内部执行魔术。或者,如果您需要在setter内部调用异步方法(这不是一个好的做法(,您可以使用OnParametersSet方法。它在参数更改后立即调用。因此,您还需要一种机制来检查标记参数是否已更改(因为它是在每次*some*参数更改时调用的(

bool tagUpdated = true;
string _tag ="";
[Parameter,SupplyParameterFromQuery] public string Tag { get => _tag; set { if (value != _tag) { _tag = value; tagUpdated = true; } } } 
protected override async Task OnParametersSetAsync()
{
if (tagUpdated)
{
tagUpdated = false;
await YourAsyncCallAndOtherMagic();
}
}

注意,SupplyFromQueryParameter仅适用于页面(具有@page指令的.razor组件(

(我想仍然不是最漂亮的解决方案。公开征求建议…(

我找到了一个解决方案。这仍然有点像黑客,但似乎有效。如果有人有更好的解决方案,请告诉我。我只是更改了事件处理程序以获取新的URL并更新页面,而不是强制重新加载。

private async void NavManager_LocationChanged(object sender, LocationChangedEventArgs e)
{
orders = await orderService.GetOrdersForTagAsync(tag);
var index = NavManager.Uri.LastIndexOf("/");
tag = NavManager.Uri.Substring(index + 1);
if (tag != "open_orders")
{
StateHasChanged();
}
}

最新更新