微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决使用 IJSRuntime Blazor 时的屏幕渲染问题

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

我目前正在通过 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;
}

在剃刀页面上定义了一个微调器,如下所示:

@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 时它不起作用?

感谢您阅读困难的英语。

解决方法

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) - 我总是忘记使用它!)

,

正如之前的评论中提到的,还有一种同步事件处理程序的方法,它在一个新任务中启动 JS Interop 并在此之后立即返回。您必须确保在完成此新任务后重新同步,使用 import cats.effect.IO import fs2.Stream val s = Stream(1,2,3,4,1,2).covary[IO] val grouped: Stream[IO,Stream[IO,Int]] = s.groupAdjacentBy(x => x == 1) .chunkN(2,allowFewer = true) .map(ch => Stream.fromIterator[IO](ch.flatMap(_._2).iterator)) val result: Stream[IO,IO[Int]] = for { group <- grouped element = group.compile.foldMonoid } yield element assertEquals(result.map(_.unsafeRunSync()).compile.toList.unsafeRunSync(),List(10,9,5)) :

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..."); } 的方法更冗长,但我认为为了完整起见,在这里提及这一点很好。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?