使用 IJSRuntime Blazor 时的屏幕渲染问题

问题描述 投票:0回答:3

首先,我对我的英语水平感到非常抱歉。

我目前正在通过 dotnet core 3.1 blazor 开发一个 Web 项目。

如下面的源代码所示,我使用 IJSRuntime 调用需要很长时间的 Javascript 函数。

[Inject]
IJSRuntime JSRuntime { get; set; }
private async Task BtnDisplay()
    await JSRuntime.InvokeVoidAsync("RefreshWebJS", Data);
}

Javascript 函数需要很长时间,所以我添加了下面的源代码来添加微调器。

private async Task BtnDisplay()
{
    showLoadingImg = true; // add
    await JSRuntime.InvokeVoidAsync("RefreshWebJS", Data);
    showLoadingImg = false;
}

在razor页面上定义了一个微调器,如下:

@if (showLoadingImg == true)
{
    <div style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; text-align: center;">
    <img src="/images/LoadingImg.gif" style="position: absolute; top: 50%; left: 50%;" />
    </div>
}

“StateHasChanged()”或“await InvokeAsync(() => StateHasChanged())”也不起作用。

当我使用 Task 而不是 JSRuntime 时,效果很好。

await Task.Delay(1000); 

为什么我使用 JSRuntime.InvokeVoidAsync 时不起作用?

谢谢您,很抱歉阅读困难的英语。

blazor asp.net-core-3.1 asp.net-core-signalr blazor-jsinterop
3个回答
5
投票
private async Task BtnDisplay()
{
    showLoadingImg = true; // add
    await Task.Delay(1);
    await JSRuntime.InvokeVoidAsync("RefreshWebJS", Data);
    showLoadingImg = false;
}

Blazor 在异步任务中完成第一个

Task
时自动重新渲染。
因此,如果第一个 

await

是您长时间运行的进程,则在完成之前它不会重新渲染。

添加 

Task

是一种允许在长时间运行的进程之前进行渲染的简单方法。

进一步阅读:

https://github.com/dotnet/aspnetcore/issues/22159

这是 Blazor 工作方式的已知功能,Blazor 的创建者也在该线程中推荐了这种方法(尽管他更喜欢

await Task.Delay(1)

- 我总是忘记使用!)

    


1
投票
await Task.Yield()

:

await InvokeAsync(StateHasChanged)

它比 Magoo 先生提出的 
private bool ShowLoading = false; private void HandleButtonClick() { ShowLoading = true; Task.Run(async () => await CallLongRunningJs()) .ContinueWith(t => { ShowLoading = false; InvokeAsync(StateHasChanged); }); } private async Task CallLongRunningJs() { await jsRuntime.InvokeVoidAsync("longRunningJsFunc", "data..."); }

的方法更冗长,但我认为为了完整性起见,最好在这里提及这一点。

    


0
投票
IJSRuntime

中有一个私有属性,其中包含Js初始化时的值(IsInitialized)。 Task.Yield()

我在 .Net 8 中多次测试过它,它可以正常工作,但在断开连接时会出现一些错误。似乎 .Net 9 中会有一个功能来处理这些问题。目前,最好的答案是使用 Try catch。

© www.soinside.com 2019 - 2024. All rights reserved.