【问题标题】:Blazor page doesn't update after calling a method调用方法后 Blazor 页面不更新
【发布时间】:2021-05-10 22:06:48
【问题描述】:

我已经构建了一个 Web 程序集 Blazor 项目。

在其中一个 blazor 组件中,有一个用于提交新数据的表单。

这种形式,通过web api将数据POST到服务器以保存在数据库中。

<EditForm Model="@person">
    <div class="col-12 row">
        <label class="col-2 font-weight-bold">Id : </label>
        <InputNumber class="form-control col-3" @bind-Value="person.Id" placeholder="id" />
    </div>
    <br />
    <div class="col-12 row">
        <label class="col-2 font-weight-bold">Name : </label>
        <InputText class="form-control col-3" @bind-Value="person.Name" placeholder="name" />
    </div>

     <input type="submit" class="form-control  btn btn-primary text-center" @onclick="@AddPerson" value="Add" />
</EditForm>

@AddPerson 背后的 C# 代码是这样的:

@code 
{

    public List<Person> people;
    public Person person = new Person();

    private async void AddPerson()
    {
        HttpResponseMessage httpResponse = await Http.PostAsJsonAsync<Person>("https://apisite.ir/api/people", person);
        people = await Http.GetFromJsonAsync<List<Person>>("https://apisite.ir/api/people");
    }

}

people 列表显示在这样的 foreach 表格中:

<table class="table">
    <thead>
        <tr>
            <th>ID</th>
            <th>Name</th>
        </tr>
    </thead>
    <tbody>
        @foreach (Person p in people)
        {
            <tr>
                <td>@p.Id</td>
                <td>@p.Name</td>
            </tr>
        }
    </tbody>
</table>

问题是,当我点击 Add button 时,两个 api 调用都会发生,但 UI 中没有任何变化。

应该显示人员列表的表格不会更新。

我该怎么办?

【问题讨论】:

    标签: c# asynchronous async-await blazor blazor-webassembly


    【解决方案1】:

    我对此进行了搜索,在调用我的 API 作为答案后,每个地方都说要添加 StateHasChanged();

    这个问题具有误导性,但我只是通过将 void 更改为 Task

    来解决它
    private async Task AddPerson()
    {
        HttpResponseMessage httpResponse = await Http.PostAsJsonAsync<Person>("https://apisite.ir/api/people", person);
        people = await Http.GetFromJsonAsync<List<Person>>("https://apisite.ir/api/people");
    }
    

    我不知道为什么会发生这种情况,因为我不擅长编写 async/await 代码,我偶然发现了这个!

    我在这里发布这个是为了帮助其他人摆脱StateHasChanged();,如果他们有同样的情况。

    【讨论】:

    • 你先生救了我的命。
    【解决方案2】:

    你不应该这样做:

    <input type="submit" class="form-control  btn btn-primary text-center" @onclick="@AddPerson" value="Add" /> 
    

    您应该这样做:

    <button type="submit">Submit</button>
    

    “提交”按钮的作用是将表单数据“提交”到服务器,这绝不应该发生,这就是为什么我使用带单引号的提交一词。而且您不应该将@onclick 指令应用于“提交”按钮。相反,您应该像这样使用 EditForm 的 OnValidSubmit 事件属性: &lt;EditForm Model="@person" OnValidSubmit="AddPerson"&gt;

    现在,当用户点击“提交”按钮时,Blazor 框架会拦截提交操作并取消它(SPA 应用程序中没有表单提交),并且如果您的模型通过验证(例如,Person.Name 不能超过 50 个字符),则调用 AddPerson 方法...

    在 Blazor 的早期开发阶段,您必须在需要重新渲染的代码中使用 StateHasChanged 方法。目前,UI 事件处理程序默认调用 StateHasChanged 方法。

    当您将方法定义为异步但返回 void (async void) 您的 UI 永远不会刷新(重新渲染),因为运行时永远不会调用 StateHasCahnged,因为运行时永远不会知道调用的异步方法何时返回,因此 AddPerson 方法的执行在不调用 StateHasCahnged 方法的情况下结束。当你使用async Task 时,Task 对象让运行时知道等待的方法已经返回,其结果是:运行时调用 StateHasCahnged 方法来通知相关组件它的状态已经改变并且它应该重新渲染。 .. 始终使用async Task

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-09-23
      • 2019-08-31
      • 2019-09-12
      • 2020-04-22
      • 2020-09-12
      • 1970-01-01
      • 1970-01-01
      • 2023-02-01
      相关资源
      最近更新 更多