c# - 如何在 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 来修饰表单?
注意:我没有进行任何更新,因此不需要索引。提交后,将删除任何现有的对,并插入表单提交的对。
解决方案
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>
}
推荐阅读
- r - 在R中将二进制列聚合为具有不同级别的一列
- recursion - 在 Dr. Racket 中,如果列表中的每个整数都是偶数,我将如何编写一个生成 true 的球拍函数,否则为 false?
- bash - 如何在符号的第一次出现和第二次出现之间替换特定行中的文本
- java - 为本地开发设置 Mockito 时遇到问题
- webpack - 为什么 webpack watch 没有更新我的代码?
- twilio - Twilio 重定向标签的问题
- flutter - Flutter - 来自 json 文件的下标
- python - PyQt5 QTabBar paintEvent 带有可以移动的标签
- amazon-dynamodb - 如何同步 Amplify DataStore 和 DynamoDB 之间的一对多关系?
- r - R函数用于根据列中的模式对行进行分组?