【问题标题】:Blazor client side refresh componentBlazor 客户端刷新组件
【发布时间】:2020-10-17 12:46:30
【问题描述】:

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

带有示例的回购链接:https://github.com/ovie91/RefreshComponent

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

所以我有从 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 :<
}

我曾尝试使用 this.StateHasChanged(); 但没有任何反应。 作为一种解决方法,我可以强制您再次导航到同一个网站,但这次刷新的是“整个”网站,而不是一个组件。

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

完整代码(精简到最少):

@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,这意味着我不必在单击按钮后再次运行相同的代码。希望你明白我的意思。

【问题讨论】:

  • 如果您发布更多代码会有所帮助。你不会在晚上向我们展示你打电话给 StateHasChanged 的​​时间/地点
  • 在 ButtonClick 中 - 我更新了帖子 :)
  • 您要更新哪些属性? - 在用户视图中
  • 我已经添加了“整个代码”,我正在尝试再次更新整个页面组件。所以点击按钮后我的数据会刷新
  • 您在按钮点击中将结果设置为空

标签: async-await blazor blazor-client-side blazor-webassembly


【解决方案1】:

要获得所需的输出,您只需将行稍微改组,来自:

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

到:

  private async void ButtonClick()
  {
     result = null;
     this.StateHasChanged();  // should show '<h3>Loading</h3>' now
     await (some API Call);       
  }

但是,从你的回答我们得到

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

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

如果您想确定:

private async Task GetData()
{
    await Task.Yield();    // 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 会更好,但这不是这里的直接问题。

【讨论】:

  • Henk,如果你有时间,你能否简要解释一下为什么你的“洗牌”有效。
  • 这是因为当您的代码awaits 某些东西时线程被释放并可以更新 UI。所以将变量设置为nullbefore等待看到&lt;p&gt;Loading...&lt;p&gt;
【解决方案2】:

来自here

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

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

所以作为 enet asnwered,你应该使用async Task 签名而不是async void

【讨论】:

  • 我认为这个问题与 SynchronizationContext 无关...
  • Repo 链接示例:github.com/ovie91/RefreshComponent 站点 /test 或来自导航菜单测试
  • @user3574248 但它有效。它使用result 的值更新自身,即使使用async void =)
【解决方案3】:

我已将 API 调用移至另一个方法,并在 OnInitializedAsync 内部调用了它。

然后,当我重置结果变量以查看加载状态时,我可以“刷新”组件以实现您需要添加的内容。 this.StateHasChanged()

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

@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(); 

    }

}

【讨论】:

  • 我的web开发经验是0,我只是在学习c#、blazor和.net core。这可能是错误的方法,但它的工作原理,所以我不知道你想用你的 cmets 实现什么。
猜你喜欢
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
  • 1970-01-01
  • 2020-04-22
  • 2021-04-01
  • 2021-12-25
  • 1970-01-01
相关资源
最近更新 更多