【问题标题】:Blazor checkbox onchange event with parameter带有参数的 Blazor 复选框 onchange 事件
【发布时间】:2020-10-08 17:40:39
【问题描述】:

以下代码适用于我:

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

【问题讨论】:

    标签: blazor blazor-webassembly


    【解决方案1】:

    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);
    }
    

    希望这会有所帮助。

    【讨论】:

    • 是的,我知道目前我正在发送所有数据(也是未更改的数据),因此我的 SO 问题 :-)。
    • 感谢您提及这一点,@KrisvanderMast。对于选项 #2,您应该使用 @key 功能。我相信这将帮助您准确了解该做什么以及如何做。如果您希望我将其包含在我的答案中,请告诉我:docs.microsoft.com/en-us/aspnet/core/blazor/components/…
    猜你喜欢
    • 2018-10-01
    • 2015-08-17
    • 2021-04-24
    • 2015-08-09
    • 2016-11-10
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多