如何在动态生成的表格中绑定下拉列表中选择的值?ASP.NET Core MVC

6
在我的ASP.NET Core MVC项目中,有一个表格包含两列下拉列表,用户需要选择费率值并点击保存按钮才能更新表格中每一行的费率值。总共有数十个动态生成的行,因此有两倍数量的下拉列表值需要跟踪。
目标是使用所选行中的两个下拉列表的值来更新每一行。
我已经创建了表格并显示出了值。有一个循环生成表格中每一行。我遇到的问题是不知道如何将所有下拉列表的值和行号一起传递回控制器,以便可以编写逻辑来更新数据库中的值。我只能传递第一行的单个下拉组合,不知道如何对所有下拉列表执行相同操作或指示它们来自哪一行。下拉列表在循环中使这个问题变得困难。
以下是我显示表格的视图部分:
      <tbody>
      @foreach (var item in Model.WorksheetRates)
      {
      var recordNumber = PagedContext.Page * PagedContext.PageSize + Model.WorksheetRates.IndexOf(item) + 1;
      <tr>
           <td>@recordNumber</td>
           <td>
               @item.Program
           </td>
           <td>
               @item.Area
           </td>
            <td>
                @Html.DropDownListFor(x => x.GARateID, gaRatesList, new { @style = "width:280px;" })
            </td>
             <td>
                 @Html.DropDownListFor(x => x.OverheadRateID, overheadRatesList, new { @style = "width:280px;" })
             </td>
         </tr>
      }
                        </tbody>

这是模型:

public class BudgetPrepViewModel
{
    public List<WorksheetRate> WorksheetRates { get; set; }

    public int GARateID { get; set; }
    public int OverheadRateID { get; set; }

    public IEnumerable<SelectListItem> GARateList { get; set; }
    public IEnumerable<SelectListItem> OverheadRateList { get; set; }
}

如您所见,我添加了IEnumerable<SelectListItem>对象,因为我认为它们需要在控制器中使用和迭代。这只是一个猜测,我不知道如何绑定它们。并且我将它们与正确的行关联起来很重要。

以下是我在标题栏中编写的代码,实际代码内容与问题无关:

[HttpPost, ActionName("SelectRates")]
public IActionResult SelectRates([Bind("GARateID, OverheadRateID")] BudgetPrepViewModel data)
{
        BPViewModel model = new BPViewModel
        {
            MonthNameList = MonthSelectList(),
            PrepStep = 8
        };

       return View("Index", model);
}

希望能得到任何帮助。如果有不清楚的地方,请告诉我,我已经尽力描述这个问题。谢谢!


1
行需要同时保存,还是在选择费率时保存?我认为你应该改变你的方法。但在此之前,我需要知道这些行是否可以独立处理。 - antoprd
@antoprd 谢谢你的答复。要求是所有行同时保存。你可以详细说明一下你认为应该如何改变方法吗? - user1179071
1个回答

2

首先,我假设WorksheetRateGARateIDOverheadRateID作为属性,因为它们位于同一行表格中。其次,我添加了一个Id属性到WorksheetRate,以便在提交表单时可以识别所选选项。也就是说,现在类是这样的:

public class WorksheetRate
{
    public int Id { get; set; }
    public string Program { get; set; }
    public string Area { get; set; }
    public int GARateID { get; set; }
    public int OverheadRateID { get; set; }
}
public class BudgetPrepViewModel
{
    public List<WorksheetRate> WorksheetRates { get; set; }

    public IEnumerable<SelectListItem> GARateList { get; set; }
    public IEnumerable<SelectListItem> OverheadRateList { get; set; }
}

重要的是,所选项和输入框的名称必须遵循一定的规则,使 ASP.NET 能够将其绑定到模型。对于这种情况,为了将值绑定到 BudgetPrepViewModel.WorksheetRates 中的 GARateID 属性,选项和输入框的名称必须如下所示:
  • 选项:
    • <select name="WorksheetRates[0].GARateID">
    • <select name="WorksheetRates[1].GARateID">
  • 输入框:
    • <input hidden name="WorksheetRates[0].Id" />
    • <input hidden name="WorksheetRates[1].Id" />
因此,解决方案是:
@for (var i=0; i<Model.WorksheetRates.Count(); i++)
{
    <tr>
        <td>
            @Model.WorksheetRates[i].Id
            <input hidden asp-for="WorksheetRates[i].Id" /> 
        </td>
        <td>
            @Model.WorksheetRates[i].Program
        </td>
        <td>
            @Model.WorksheetRates[i].Area
        </td>
        <td>
            @Html.DropDownListFor(x => x.WorksheetRates[i].GARateID, Model.GARateList, new { @style = "width:280px;" })
        </td>
        <td>
            @Html.DropDownListFor(x => x.WorksheetRates[i].OverheadRateID, Model.OverheadRateList, new { @style = "width:280px;" })
        </td>
    </tr>
}

我已经创建了一个存储库,其中包含完整的工作解决方案。


非常感谢您的回复。我需要一些时间来仔细阅读您的答案,然后再与您联系。 - user1179071
1
谢谢您的回答。非常清晰且有帮助。 - user1179071

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接