End*_*ono 5 blazor blazor-client-side
我正在使用NavigationManager.LocationChanged捕获查询字符串。获取查询字符串值后,我进行了 ajax 调用,这是异步的。LocationChanged 本身是同步方法,貌似没有异步版本的LocationChanged. 并且在LocationChanged内部调用async方法时,async方法设置的值落后一步。
这是重现:
@page "/investigate"
@implements IDisposable
@inject NavigationManager NM
<h1>Sync: @SyncValue</h1>
<h1>Async: @AsyncValue</h1>
<button @onclick="TriggerLocationChange">Increment</button>
@code {
private string SyncValue;
private string AsyncValue;
private int Counter = 1;
protected override void OnInitialized()
{
NM.LocationChanged += OnLocationChanged;
}
public void Dispose()
{
NM.LocationChanged -= OnLocationChanged;
}
private void OnLocationChanged(object sender, LocationChangedEventArgs args)
{
// sync action, just for comparison
SyncValue = (Counter * 1000).ToString();
DoSomeAsync();
}
private async Task DoSomeAsync()
{
// http call to server
await Task.Delay(1);
AsyncValue = (Counter * 1000).ToString();
}
private void TriggerLocationChange()
{
Counter++;
NM.NavigateTo("investigate?counter=" + Counter);
}
}
Run Code Online (Sandbox Code Playgroud)
该@AsyncValue滞后从一个落后一步@SyncValue。
从 LocationChanged 内部调用时,如何防止异步方法滞后?
经过大量的试验和错误,这是我发现的:
LocationChanged 运行时尚未设置路由参数值。这在我上面的例子中没有显示,但对我来说很重要。可以从 URL 中手动提取路由参数,或者我们可以等到 blazor 使用await Task.Delay(1).
StateHasChanged()在异步方法结束时调用。
根据文档,我们应该用base.InvokeAsync(() => ...)
经过这些修改后, OnLocationChanged 变为:
private void OnLocationChanged(object sender, LocationChangedEventArgs args)
{
// ...
base.InvokeAsync(async () =>
{
await Task.Delay(1); // wait for blazor to populate route parameters
await DoSomeAsync();
StateHasChanged();
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1250 次 |
| 最近记录: |