以下代码对我有用:
@if (data == null)
{
<p><em>Loading...</em></p>
}
else
{
<button class="btn btn-primary" @onclick="Save">Save all changes</button>
<table class="table">
<thead>
<tr>
<th>Concern ID</th>
<th>CDC</th>
<th>Context</th>
<th>Reporting</th>
</tr>
</thead>
<tbody>
@foreach (var c in data)
{
<tr>
<td>@c.ConcernId</td>
<td><input type="checkbox" @bind="@c.PassingAllowed" /></td>
<td><input type="checkbox" @bind="@c.ContextPassingAllowed" /></td>
<td><input type="checkbox" @bind="@c.ReportingPassingAllowed" /></td>
</tr>
}
</tbody>
</table>
}
@code{
private ConcernData[] data;
protected override async Task OnInitializedAsync()
{
await GetData().ConfigureAwait(false);
}
private async Task GetData()
{
data = await Http.GetFromJsonAsync<ConcernData[]>("ConcernFilter").ConfigureAwait(false);
}
private async Task Save()
{
await Http.PostAsJsonAsync<ConcernData[]>("ConcernFilter/Update", data).ConfigureAwait(false);
}
private async Task Update(int concernId)
{
Console.Write(concernId);
}
}
但是,这会将所有(已更改和未更改的)数据发送回服务器,在这里我需要弄清楚(或简单地一个接一个地更新)数据库中哪些数据需要更新。
感觉不对劲,因为我通过网络发送了太多数据,并向数据库发送了太多更新语句(本例中为3)。
我可以想到几种解决方法:
我正在寻求帮助以完成选项2。
答案 0 :(得分:2)
在Blazor中没有“魔法”。除非您进行实际跟踪,否则无法知道哪些行已更新。这只是故事的一半。
您的代码-Save()
方法实际上将完整的data
数组发布到服务器。
听起来您正在寻找的是解决这两个问题。为此,您将需要:
Save
方法以使用该新列表,以便仅将更改后的行中的数据发送到服务器,而不是整个数据集。这里是Blazor特定的部分,您实际上是如何检测已更改的行的。实际上,您可以通过稍微修改数据模型,引入状态跟踪逻辑并通过属性公开它来简化此过程。以下只是一个简单的演示:
public class ConcernData
{
internal bool StateChanged {get; private set;}
public bool PassingAllowed
{
get => _passingAllowed;
set
{
if (value != _passingAllowed)
{
_passingAllowed = value;
StateChanged = true;
}
}
}
// Similar change detection logic goes for the rest of the properties
}
请注意,这是非常幼稚的实现,不能解决用户将数据再次更改回其原始值的情况。但是,这将使您能够如下更新Save
方法:
private async Task Save()
{
await Http.PostAsJsonAsync<ConcernData[]>("ConcernFilter/Update", data.Where(c=>c.StateChanged)).ConfigureAwait(false);
}
希望这会有所帮助。