1

以下代码适用于我:

@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 个)。

我可以想到几种方法来解决这个问题:

  1. 在客户端将更改后的列表与原始列表进行比较,仅将项目发送到真正需要更新的服务器。
  2. 找到一种方法在 Blazor 中为此类列表中的复选框编写如何调用 Update 方法并将正确的关注 ID 作为参数传递。

我正在寻求帮助来完成选项 2。

4

1 回答 1

2

Blazor 中没有“魔法”。除非您实际跟踪它,否则它无法知道哪些特定行已被更新。这只是故事的一半。您的代码 - 该Save()方法实际上将整个data数组发布到服务器。

听起来您正在寻找的是解决这两个问题。为此,您将需要:

  1. 跟踪更改的行并可能将它们存储在单独的数组中的逻辑
  2. 更新您的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);
}

希望这可以帮助。

于 2020-06-18T19:57:04.807 回答