Reputation: 16613
The following code works for me:
@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);
}
}
However this sends over all the data (changed and unchanged) back to the server where I need to figure out (or simply update one by one) which data needs an update in the databases.
It doesn't feel right as I'm sending too much data over the wire and sending too many update statements to the databases (3 in this case).
I can think of several way to tackle this:
I'm looking for help to accomplish option 2.
Upvotes: 1
Views: 2365
Reputation: 2887
There is no "magic" in Blazor. It has no way to know which particular rows have been updated, unless you actually track that. And that's only half of the story.
Your code - the Save()
method, actually posts the full data
array to the server.
It sounds like what you're looking for is to address both of these concerns. For that you will need:
Save
method to use that new list instead, to send to the server only the data from the changed rows, not the entire data set.The piece which is Blazor specific here, is how you actually detect the rows which were changed. You can actually simplify this by slightly modifying your data model, by introducing state tracking logic and exposing that through a property. The following is a simple demonstration only:
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
}
Note, that this is very naive implementation, which doesn't account for situations, where the users changes the data back to its original value again. But, this will enable you to update the Save
method as follows:
private async Task Save()
{
await Http.PostAsJsonAsync<ConcernData[]>("ConcernFilter/Update", data.Where(c=>c.StateChanged)).ConfigureAwait(false);
}
Hope this helps.
Upvotes: 2