带有参数的Blazor复选框onchange事件

时间:2020-06-18 15:39:06

标签: blazor blazor-webassembly

以下代码对我有用:

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

1 个答案:

答案 0 :(得分: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);
}

希望这会有所帮助。