Blazor 客户端刷新组件



我正在尝试弄清楚如何在单击按钮后刷新客户端组件。

带有示例的存储库链接:https://github.com/ovie91/RefreshComponent

站点/测试或从导航菜单测试

所以我有从 API 检索数据的 OnInitializedAsync 方法

protected override async Task OnInitializedAsync()
{
result = await (some API Call);
}

然后我有一个连接到按钮的方法

private async void ButtonClick()
{
await (some API Call);
result = null;
this.StateHasChanged(); <--- Doesnt work :<
}

我试图使用它。状态已更改((;但是没有反应。 作为一种解决方法,我可以强制您再次导航到同一网站,但刷新"整个"网站而不是组件。

关于如何处理它的任何想法?

整个代码(剥离到最低限度(:

@page "/test"
@inject HttpClient Http
@if (result == null)
{
<p>Loading...<p>
}
else
{
@result
<button @onclick="(() => ButtonClick())">Click</button>
}
@code {
private APIObject result;
protected override async Task OnInitializedAsync()
{
result = await (some API Call);
}
private async void ButtonClick()
{
await (some API Call);
result = null;
this.StateHasChanged(); <--- Doesnt work :<
}
}

更新我想刷新组件,以便再次触发OnInitializedAsync,这意味着我不必在单击按钮后再次运行相同的代码。希望你明白我的意思。

要获得所需的输出,您只需从以下位置稍微打乱行:

private async void ButtonClick()
{
await (some API Call);   // UI checks if an update is needed (No)
result = null;           // now an update is needed
this.StateHasChanged(); <--- Doesnt work :<  // actually: not needed
}

自:

private async Task ButtonClick()
{
result = null;             // change the state
//this.StateHasChanged();  // not needed, a request is pending
await (some API Call);     // should show '<h3>Loading</h3>' now    
}

请注意,当await释放线程时,UI 会更新。

但是,从您的回答中,我们得到

var APICall = await Http.GetAsync("SomeAPI");
Thread.Sleep(2000);

Http.GetAsync("SomeAPI");确实是一个异步调用而不仅仅是一些备用伪代码时,这应该有效。因为Thread.Sleep(2000);真的会冻结东西。

如果要确保:

private async Task GetData()
{
await Task.Delay(1);    // release the thread for rendering
var APICall = await Http.GetAsync("SomeAPI");
Random rnd = new Random();
Thread.Sleep(2000);  // Task.Delay() is much preferred
result = "Random Number: " + rnd.Next();
}

Thread.Sleep()适用于模拟某些 CPU(非 I/O(密集型代码。所以我不是说这是错的,但要意识到其中的区别。

使事件处理程序async Task而不是async void要好得多,但这不是这里的直接问题。

从这里:

Blazor 使用同步上下文 (同步上下文( 强制实施单个逻辑执行线程。组件的生命周期方法和 Blazor 引发的任何事件回调在同步上下文中执行。

Blazor Server 的同步上下文尝试模拟单线程环境,以便它与浏览器中的 WebAssembly 模型(单线程(紧密匹配。在任何给定的时间点,工作只在一个线程上执行,给人一种单一逻辑线程的印象。没有两个操作同时执行。

因此,作为enetasnwered,您应该使用async Task签名而不是async void

我已经将API调用移动到另一个方法,并且在OnInitializedAsync中我调用了它。

然后,当我重置结果变量以查看加载状态时,我可以"刷新"组件以实现您需要添加的内容。状态已更改((

现在我有一个响应组件来响应正在发生的更新:)

@page "/test"
@using System.Threading;
@inject HttpClient Http
@if (result == null)
{
<h3>Loading</h3>
}
else
{
@result
<button @onclick="(() => ButtonClick())">Click</button>
}


@code {
private string result;
protected override async Task OnInitializedAsync()
{
await GetData();
}
private async Task GetData()
{
var APICall = await Http.GetAsync("SomeAPI");
Random rnd = new Random();
Thread.Sleep(2000);
result = "Random Number: " + rnd.Next();
}
private async Task ButtonClick()
{
await Http.GetAsync("SomeAPIcall");
result = null; // required to see loading state.
this.StateHasChanged(); // when added model is refreshed and Loading state is visible.
await GetData(); 
}
}

相关内容

  • 没有找到相关文章

最新更新