我有一个包含用户列表的ViewModel。在我看来,我想动态地添加和删除该列表中的用户,但也使用@Html.EditorFor
辅助方法。
public class CreateTenantViewModel
{
[Required(ErrorMessage = "The name is required")]
public string Name { get; set; }
[Display(Name = "Email address")]
[Required(ErrorMessage = "The email address is required")]
[EmailAddress(ErrorMessage = "Invalid email address")]
public string Email { get; set; }
public List<CreateTenantUserViewModel> Users { get; set; }
[Required(ErrorMessage = "You need to accept the terms and conditions")]
public bool TermsAndConditions { get; set; }
}
public class CreateTenantUserViewModel
{
public string Firstname { get; set; }
public string Lastname { get; set; }
[Display(Name = "Email address")]
[Required(ErrorMessage = "The email address is required")]
[EmailAddress(ErrorMessage = "Invalid email address")]
public string Email { get; set; }
public bool Admin { get; set; } = false;
}
在我看来,模型创建的代码如下所示。
<table id="user-table" class="table table-hover">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Admin?</th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="add-user-row hidden">
<td>
<div class="form-group no-margins">
@Html.LabelFor(model => model.Users[-1].Firstname, new {@class = "sr-only"})
@Html.EditorFor(model => model.Users[-1].Firstname, new {htmlAttributes = new {@placeholder = Html.DisplayNameFor(model => model.Users[-1].Firstname)}})
<span class="text-danger">@Html.ValidationMessageFor(model => model.Users[-1].Firstname)</span>
</div>
</td>
<td>
<div class="form-group no-margins">
@Html.LabelFor(model => model.Users[-1].Lastname, new {@class = "sr-only"})
@Html.EditorFor(model => model.Users[-1].Lastname, new {htmlAttributes = new {@placeholder = Html.DisplayNameFor(model => model.Users[-1].Lastname)}})
<span class="text-danger">@Html.ValidationMessageFor(model => model.Users[-1].Lastname)</span>
</div>
</td>
<td>
<div class="form-group no-margins">
@Html.LabelFor(model => model.Users[-1].Email, new {@class = "sr-only"})
@Html.EditorFor(model => model.Users[-1].Email, new {htmlAttributes = new {@placeholder = Html.DisplayNameFor(model => model.Users[-1].Email)}})
<span class="text-danger">@Html.ValidationMessageFor(model => model.Users[-1].Email)</span>
</div>
</td>
<td>@Html.CheckBoxFor(model => model.Users[-1].Admin)</td>
<td><i class="fa fa-trash fa-2x text-danger pointer" onclick="$(this).closest('tr').remove();"></i></td>
</tr>
<tr id="add-user">
<td colspan="4"><button class="btn btn-primary" onclick="addUserRow(); return false;"><i class="fa fa-plus"></i> Add user</button></td>
</tr>
</tbody>
我使用上面的表格行作为模板,点击按钮时通过jquery复制:
function addUserRow() {
var clone = $("#user-table tbody > tr:first").clone();
// count up the user number
clone.html(function () {
return clone.html().replace(new RegExp("-1", "g"), count);
});
clone.find("input:checkbox").iCheck({
checkboxClass: 'icheckbox_square-green'
});
$("#user-table tr:last").before(clone.removeClass("hidden"));
count++;
}
但是也可以删除中间的行。问题是MVC似乎没有绑定数组中的所有项。它只需要第一项。如果索引中存在间隙,例如用户[0] .Name,Users [3] .Name它只会绑定到第一个项目。 所有项目都在请求中传递。
我还尝试使用jquery修复索引,但它似乎不起作用:
var form = $(this);
$("tr.add-user-row.hidden").remove();
var regExp = new RegExp("(Users.)(\d)", "g");
$("tr.add-user-row")
.each(function (index) {
var that = $(this);
that.html(function () {
return that.html().replace(regExp, "$1" + index);
});
alert(that.html());
});
// Submit form input
form.submit();
如何修复此jquery函数,甚至更好:使MVC绑定到请求中提交的所有项目,而不管它们在数组中的顺序如何?