简体   繁体   English

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

[英]I need to update a Blazor page to update whenever the query string changes

I have a Blazor component named NavBar.razor that displays a Radzen navigation menu with a list of tags.我有一个名为 NavBar.razor 的 Blazor 组件,它显示带有标签列表的 Radzen 导航菜单。 When the user clicks a tag (RadzenPanelMenuItem), the component OrderBrowser.razor is loaded into the page next to the menu.当用户单击标签 (RadzenPanelMenuItem) 时,组件 OrderBrowser.razor 被加载到菜单旁边的页面中。 The query string lets OrderBrowser.razor know what tag was selected.查询字符串让 OrderBrowser.razor 知道选择了什么标签。 (See the OnInitializedAsync method below.) The component loads the associated orders into a grid. (请参阅下面的 OnInitializedAsync 方法。)该组件将关联的订单加载到网格中。

This works fine the first time the user clicks a tag, but when they click a different tag, the OnInitializedAsync method does not execute, even though the uri changes.这在用户第一次单击标签时工作正常,但当他们单击不同的标签时,即使 uri 发生变化,OnInitializedAsync 方法也不会执行。 So I added an event handler to force a reload when the uri changes.所以我添加了一个事件处理程序以在 uri 更改时强制重新加载。 This works, but, for some reason, it seems to reload twice, resulting in an undesirable blink when it reloads the 2nd time.这行得通,但由于某种原因,它似乎重新加载了两次,导致第二次重新加载时出现不希望的闪烁。

Does anyone know a better way to do this?有谁知道更好的方法吗? Thanks.谢谢。

Code from NavBar.razor:来自 NavBar.razor 的代码:

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

Order grid from OrderBrowser.razor:来自 OrderBrowser.razor 的订单网格:

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

Code from OrderBrowser.razor:来自 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);
}

Use this event使用此事件

[Parameter]
[SupplyParameterFromQuery]
public string? Page { get; set; } = "0";

    protected override void OnParametersSet()
    {
     //Fire your Code her
    }

I found a solution.我找到了解决方案。 It's still a bit of a hack, but it seems to work.它仍然有点黑客,但它似乎工作。 If anybody has any better solutions, please let me know.如果有人有更好的解决方案,请告诉我。 I just changed the event handler to get the new URL and update the page, instead of forcing a reload.我只是更改了事件处理程序以获取新的 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();
    }
}

When you go from: yourUrl/tag/tagname1 and click to link yourUrl/tag/tagname2 it does not fire OnInitializedAsync , because new page was not created.当您 go 来自: yourUrl/tag/tagname1并单击以链接yourUrl/tag/tagname2时,它不会触发OnInitializedAsync ,因为未创建新页面。 It is intended and correct behavior.这是有意的和正确的行为。 But bit confusing.但有点混乱。

You can leverage new, with .net6 introduced, capability of SupplyFromQueryParameter attribute, which will change its value based on query string.您可以利用 .net6 引入的SupplyFromQueryParameter属性的新功能,该属性将根据查询字符串更改其值。

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

Now you can do the magic inside seeter of the Tag property.现在您可以在Tag属性的 Seeter 中发挥作用。 Or, if you need to call async method inside setter (which is not a good practice), you can use OnParametersSet method.或者,如果您需要在 setter 中调用异步方法(这不是一个好习惯),您可以使用OnParametersSet方法。 It is called right after parameters has been changed.它在参数更改后立即调用。 So you also need a mechanism to check if tag parameter has been changed (because it is called every time *some* parameter has been changed )因此,您还需要一种机制来检查标记参数是否已更改(因为每次 *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();
    }
}

Note, that SupplyFromQueryParameter works only on pages ( .razor components with @page directive)请注意, SupplyFromQueryParameter仅适用于页面(带有@page指令的.razor组件)

(still not the most beautiful solution I guess. Open for suggestions...) (仍然不是我猜的最漂亮的解决方案。欢迎提出建议......)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM