首页 > 解决方案 > 如何在 Razor/.NET Core PageModel 中绑定动态长度列表<>,而不依赖 JavaScript 重新索引每个输入?

问题描述

我有一个表单,用户可以在其中提供任意长度的<DateTime, int>对列表。它是这样表示的:

List<ItemsPerDay> ItemsPerDayList = new List<ItemsPerDay>();
public class ItemsPerDay {
  public DateTime Date { get; set; }
  public int Amount { get; set; }
}
<tbody>
  @{ var i = 0; } 
  @foreach (var _ in Model.ItemsPerDayList) {
    <tr>
      <td><input asp-for="ItemsPerDayList[i].Date" type="date" /></td>
      <td><input asp-for="ItemsPerDayList[i].Amount" /></td>
      <td><a class="remove">Remove</a></td>
    </tr>
    i++; 
  }
</tbody>

问题:

用户可以根据需要添加/删除行。但是,属性绑定依赖于正确索引的对。例如,如果您删除了第一项,则列表现在开始于[1]并且属性绑定不起作用;ItemsPerDayList发布为null.

我目前的解决方法:

我不得不使用一些 JavaScript 来确保索引始终保持正确。这有效,但不是最佳的。

function reIndexItemRows() {
  $("table > tbody > tr").each(function(idx) {
    $(this).find("input[type=date]").attr({
      "data-val": true,
      "data-val-required": "The Date field is required.",
      id: `ItemsPerDayList_${idx}__Date`,
      name: `ItemsPerDayList[${idx}].Date`
    });

    $(this).find("input[type=number]").attr({
      "data-val": true,
      "data-val-required": "The Amount field is required.",
      id: `ItemsPerDayList_${idx}__Amount`,
      name: `ItemsPerDayList[${idx}].Amount`
    });
  });
}

问题:

在前端表示此模型的适当方式是什么,这样我就不必在每次添加或删除行时都依赖 JavaScript 来修饰表单?

注意:没有进行任何更新,因此不需要索引。提交后,将删除任何现有的对,并插入表单提交的对。

标签: c#.netasp.net-corerazor

解决方案


JavaScript 是调整索引所必需的。您可以在提交表单时添加事件来调整索引。

在Remove上添加一个事件。这是表格。

<form  method="post" id="myform">
<table>
    <tbody>
        @{ var i = 0; }
        @foreach (var _ in Model.ItemsPerDayList)
        {
            <tr>
                <td><input asp-for="ItemsPerDayList[i].Date" type="date" /></td>
                <td><input asp-for="ItemsPerDayList[i].Amount" /></td>
                <td><a class="remove" onclick="remove(this)" >Remove</a></td>
            </tr>
            i++;
        }
    </tbody>
</table>
<input type="submit" name="name" value="submit" />
</form>

<button id="add" onclick="add()" class="btn-primary">add</button>

在提交表单之前,javascript 会迭代每一行并修改索引。

@section Scripts{
<script>
    $('#myform').submit(function () {
        var i = 0;
        $("tbody> tr ").each(function () {
            $(this).find("td input[name$='Date']").attr("name", "ItemsPerDayList[" + i + "].Date");
            $(this).find("td input[name$='Amount']").attr("name", "ItemsPerDayList[" + i + "].Amount");
            i++
        })
        // ...
        return true; // return false to cancel form action
    });

    function remove(e) {
        $(e).parent().parent().remove()
    }
    function add() {
        $('tbody').append('<tr><td> <input name="ItemsPerDayList[i].Date" type="date" /></td ><td><input name="ItemsPerDayList[i].Amount" /><td><a class="remove" onclick="remove(this)">Remove</a></td></tr>');
    }
</script>

 }

然后,我可以从前端获取所有数据。 在此处输入图像描述


推荐阅读