调用方法后 Blazor 页面不更新
Blazor page doesn't update after calling a method
我已经构建了一个 web assembly blazor 项目。
在其 blazor 组件之一中,有一个用于提交新数据的表单。
这个表格,POST数据通过网络传送到服务器api保存在数据库中。
<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 列表显示在这样的 table 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>
问题是,当我单击“添加”按钮时,两个 api 调用都会发生,但 UI 中没有任何变化。
本应显示人员列表的table不会更新。
我该怎么办?
我搜索了这个,每个地方都说在给我的 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();
如果他们有同样的情况。
你不应该这样做:
<input type="submit" class="form-control btn btn-primary text-center" @onclick="@AddPerson" value="Add" />
您应该这样做:
<button type="submit">Submit</button>
“提交”按钮的作用是'submit'将表单数据发送到服务器,这种情况是不应该发生的,这就是为什么我用单引号来提交这个词。并且您不应该将 @onclick
指令应用于“提交”按钮。相反,您应该像这样使用 EditForm 的 OnValidSubmit
事件属性:
<EditForm Model="@person" OnValidSubmit="AddPerson">
现在,当用户点击“提交”按钮时,Blazor 框架拦截提交操作并取消它(SPA 应用程序中没有表单提交),如果您的模型通过验证(例如,Person.Name 不能超过 50 个字符),然后调用 AddPerson 方法...
在 Blazor 的早期开发阶段,您必须在需要重新呈现的代码中使用 StateHasChanged 方法。目前,StateHasChanged 方法默认从 UI 个事件处理程序中调用。
当您将方法定义为异步时 returning void (async void)
您的 UI 永远不会刷新(重新呈现),因为运行时永远不会调用 StateHasCahnged,因为运行时永远不知道异步方法何时调用 return,因此也不知道 AddPerson 方法的执行在不调用 StateHasCahnged 方法的情况下结束。当您使用 async Task
时,Task 对象让运行时知道等待的方法已 returned,其结果:运行时调用 StateHasCahnged 方法通知相关组件其状态已更改,并且它应该重新渲染...总是使用 async Task
我已经构建了一个 web assembly blazor 项目。
在其 blazor 组件之一中,有一个用于提交新数据的表单。
这个表格,POST数据通过网络传送到服务器api保存在数据库中。
<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 列表显示在这样的 table 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>
问题是,当我单击“添加”按钮时,两个 api 调用都会发生,但 UI 中没有任何变化。
本应显示人员列表的table不会更新。
我该怎么办?
我搜索了这个,每个地方都说在给我的 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();
如果他们有同样的情况。
你不应该这样做:
<input type="submit" class="form-control btn btn-primary text-center" @onclick="@AddPerson" value="Add" />
您应该这样做:
<button type="submit">Submit</button>
“提交”按钮的作用是'submit'将表单数据发送到服务器,这种情况是不应该发生的,这就是为什么我用单引号来提交这个词。并且您不应该将 @onclick
指令应用于“提交”按钮。相反,您应该像这样使用 EditForm 的 OnValidSubmit
事件属性:
<EditForm Model="@person" OnValidSubmit="AddPerson">
现在,当用户点击“提交”按钮时,Blazor 框架拦截提交操作并取消它(SPA 应用程序中没有表单提交),如果您的模型通过验证(例如,Person.Name 不能超过 50 个字符),然后调用 AddPerson 方法...
在 Blazor 的早期开发阶段,您必须在需要重新呈现的代码中使用 StateHasChanged 方法。目前,StateHasChanged 方法默认从 UI 个事件处理程序中调用。
当您将方法定义为异步时 returning void (async void)
您的 UI 永远不会刷新(重新呈现),因为运行时永远不会调用 StateHasCahnged,因为运行时永远不知道异步方法何时调用 return,因此也不知道 AddPerson 方法的执行在不调用 StateHasCahnged 方法的情况下结束。当您使用 async Task
时,Task 对象让运行时知道等待的方法已 returned,其结果:运行时调用 StateHasCahnged 方法通知相关组件其状态已更改,并且它应该重新渲染...总是使用 async Task