gpt4 book ai didi

blazor - 在 Blazor 中,为什么调用 NavigationManager.NavigateTo 有时会导致使用旧值进行额外的 OnParametersSetAsync 调用?

转载 作者:行者123 更新时间:2023-12-04 14:11:21 34 4
gpt4 key购买 nike

在 Blazor 中,为什么调用 NavigationManager.NavigateTo(string) 有时会导致使用旧值额外调用 OnParametersSetAsync 调用?

我有一个页面通过 CallbackEvent 响应点击,父级调用 NavigationManager.NavigateTo 来设置新的 URL,这会导致父级的参数更新,然后组件通过 OnParametersSetAsync 响应新值。 但在此之前,还使用旧值调用了 OnParametersSetAsync——显然是在它们更改之前。似乎我的第二次调用经常在第一次(错误的)调用之前完成,因此第一次调用最后完成,结果很糟糕。

那么,这第一次看似虚假且不正确的对 OnParametersSetAsync 的调用是否只是因为在事件处理程序等待时属性可能已更改而发生?我如何确定这是一个虚假电话?

这是一个触发它的例子:

@page "/demo"
@page "/demo/{SelectedOrderId:int}"

@using Microsoft.Extensions.Configuration

@inject IHttpClientFactory clientFactory
@inject IToastService toastService
@inject IConfiguration Configuration
@inject NavigationManager navigationManager

<div class="mt-4 container-fluid">
<div class="row">
<div class="col-12 col-md-8 order-md-2">
Order @OrderDetail?.OrderId @OrderDetail?.ProductCode
</div>
<div class="col-12 col-md-4 order-md-1">
@foreach (var order in Orders)
{
<button @onclick="async () => await OnSelectedOrderIdChanged(order.OrderId)">@order.OrderId</button> }
</div>
</div>

</div>

@code {
[CascadingParameter]
public AppState State { get; set; } = null!;

public int? CustomerId { get; set; } = 8010;

[Parameter]
public int? SelectedOrderId { get; set; } = null;

private List<Order> Orders { get; set; } = new List<Order>();
private OrderDetail? OrderDetail { get; set; } = null;


protected override async Task OnInitializedAsync()
{
await LoadOrdersList();
}

protected override async Task OnParametersSetAsync()
{
Console.WriteLine($"params changed to order {SelectedOrderId}");
await LoadOrderDetail();
Console.WriteLine($"done loading order {SelectedOrderId}");

}

private async Task LoadOrdersList()
{
string serviceEndpoint = Configuration["MyServiceUrl"];
string url = $"{serviceEndpoint}/orders?customerId={CustomerId}";
Orders = await clientFactory.CreateClient().GetFromJsonAsync<List<Order>>(url);
}

private async Task LoadOrderDetail()
{
string serviceEndpoint = Configuration["MyServiceUrl"];
string url = $"{serviceEndpoint}/orders/{SelectedOrderId}";
OrderDetail = await clientFactory.CreateClient().GetFromJsonAsync<OrderDetail>(url);
}


private async Task OnSelectedOrderIdChanged(int? newOrderId)
{
SelectedOrderId = newOrderId;
await Task.Yield(); // could be anything
navigationManager.NavigateTo($"/demo/{newOrderId}");
}
}

当我运行它然后点击订单 48026528 的其中一个按钮时,我进入了控制台:

params changed to order 48026500

params changed to order 48026528

done loading order 48026528

并且页面显示显示订单48026500!据推测,应该导致的 UI 更新发生得早。那么我如何确定对 48026500 的调用是伪造的(或者它不代表对参数的真正更改)?

我尝试跟踪先前的值并将其与当前值进行比较,但这没有帮助,因为"new"值是在旧值之前处理的——换句话说,上面的 LoadOrderDetail()运行两次,然后他们进行比赛,通常具有新值的 LoadOrderDetail 首先运行,然后具有旧值的 LoadOrderDetail 完成并覆盖新数据。那么如何避免在这些虚假事件上调用 LoadOrderDetail?

最佳答案

NavigationManager.NavigateTo(string) 仅调用一次。这是您的问题(您非常接近!):

[Parameter]
public int? SelectedOrderId { get; set; } = null;

. . . . .

private async Task OnSelectedOrderIdChanged(int? newOrderId)
{
// Setting a [Parameter] prop might "work", but is not intended
SelectedOrderId = newOrderId;
await Task.Yield();
// This will also update SelectedOrderId
navigationManager.NavigateTo($"/demo/{newOrderId}");
}

请注意,[Parameter] 属性应该由父级或通过 @page 路由参数设置,而不是由组件本身设置。

navigationManager.NavigateTo($"/demo/{newOrderId}"); 将设置 SelectedOrderId;这是更新页面 [Parameter] 属性的正确方法! 因此,SelectedOrderId = newOrderId 不是必需的。删除该行,您的代码应按预期工作。


此外,您提到跟踪先前的值以确定何时更新。这可能很有用(尤其是与 ShouldRender 配对时)。最简单的方法是跟踪以前的 id 而不是以前的值。应用于您的代码:

[Parameter]
public int? SelectedOrderId { get; set; }

private int? PreviousOrderId { get; set; }

. . . . .
protected override async Task OnParametersSetAsync()
{
Console.WriteLine($"params changed to order {SelectedOrderId}");
if (PreviousOrderId != SelectedOrderId) {
// Prevent the load from ever happening if the id doesn't change.
await LoadOrderDetail();
}
PreviousOrderId = SelectedOrderId;
Console.WriteLine($"done loading order {SelectedOrderId}");
}

关于blazor - 在 Blazor 中,为什么调用 NavigationManager.NavigateTo 有时会导致使用旧值进行额外的 OnParametersSetAsync 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63945954/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com