asp.net 核心 mvc 模型与 jquery 中继器绑定
asp.net core mvc model binding with jquery repeater
我在我的表单中使用 jquery 转发器来动态地仅将输入组的一部分添加到表单中。我确实尝试过,但无法将输入绑定到模型,我失明了。
这是我的模型。
public class SuggestionCreateEditViewModel
{
public Guid[] DetectionId { get; set; }
public SuggestionCreateEditRepeatedModel[] Repeated { get; set; }
}
public class SuggestionCreateEditRepeatedModel
{
public Guid To { get; set; }
public string Description { get; set; }
public DateTime Deadline { get; set; }
}
表格,为了简洁我删除了很多表格部分
<div class="col-lg-9 col-md-9 col-sm-12">
<select asp-for="DetectionId" asp-items="ViewBag.AllDetections" class="m-bootstrap-select m_selectpicker toValidate"
multiple data-actions-box="true" data-width="100%"></select>
</div>
<div class="col-lg-9 col-md-9 col-sm-12 input-group date">
<input name = "Repeated.Deadline" type="text" readonly class="form-control toValidate dtDueDate" />
</div>
<div class="col-lg-12 col-md-12 col-sm-12">
<textarea name = "Repeated.Description" class="form-control toValidate txtSuggestion" type="text" >
</textarea>
</div>
在将新的重复部分添加到表单之后并在将其发布到服务器之前,如果我 form.serailizeArray()
它 returns 集合如下(jquery 表单转发器动态形状名称我相信)
{name: "DetectionId", value: "afca1b82-0455-432e-c780-08d6ac38b012"}
{name: "[0][Repeated.To][]", value: "b1176b82-1c25-4d13-9283-df2b16735266"}
{name: "[0][Repeated.Deadline]", value: "04/04/2019"}
{name: "[0][Repeated.Description]", value: "<p>test 1</p>"}
{name: "[1][Repeated.To]", value: "188806d8-202a-4787-98a6-8dc060624d93"}
{name: "[1][Repeated.Deadline]", value: "05/04/2019"}
{name: "[1][Repeated.Description]", value: "<p>test 2</p>"}
和我的控制器
[HttpPost]
public IActionResult CreateSuggestion(SuggestionCreateEditViewModel model, IFormFile[] documents)
{...
控制器无法绑定 Repeated
,仅绑定了 DetectionId
。我应该如何塑造我的模型来获取数据?
从表面上看,控制器无法将转发器属性绑定回您的视图模型,因为发布内容的命名与您视图模型中的命名不匹配(如 Topher 所述)。
DetectionId 的命名正确,因为 属性 的名称匹配但它不是数组。
要解析数组,我们需要确保在表单中包含 属性 名称以及索引,以便 mvc 模型绑定知道将结果绑定到何处。
这样,您可以尝试将名称的格式更改为:
已重复[0].到
这应该与您的控制器匹配并正确绑定。
有关绑定的更多信息,请参阅this。
这是 jquery.repeater.js
的工作演示,请注意这一行 <div data-repeater-list="Repeated">
,它将像 name="Repeated[0][Description]"
一样格式化字段
@model TestCore.Models.SuggestionCreateEditViewModel
@{
ViewData["Title"] = "Contact";
}
<form class="repeater" asp-action="CreateSuggestion" method="post">
<!--
The value given to the data-repeater-list attribute will be used as the
base of rewritten name attributes. In this example, the first
data-repeater-item's name attribute would become group-a[0][text-input],
and the second data-repeater-item would become group-a[1][text-input]
-->
<div data-repeater-list="Repeated">
<div data-repeater-item>
<div class="col-lg-9 col-md-9 col-sm-12">
<select asp-for="DetectionId" asp-items="ViewBag.AllDetections" class="m-bootstrap-select m_selectpicker toValidate"
multiple data-actions-box="true" data-width="100%"></select>
</div>
<div class="col-lg-12 col-md-12 col-sm-12">
<textarea name="Description" class="form-control toValidate txtSuggestion" type="text">
</textarea>
</div>
</div>
</div>
<input data-repeater-create type="button" value="Add" />
<input type="submit" value="Submit"/>
</form>
@section Scripts{
<!-- Import repeater js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.repeater/1.2.1/jquery.repeater.js"></script>
<script>
$(document).ready(function () {
$('.repeater').repeater({
// (Optional)
// start with an empty list of repeaters. Set your first (and only)
// "data-repeater-item" with style="display:none;" and pass the
// following configuration flag
initEmpty: true,
// (Optional)
// "show" is called just after an item is added. The item is hidden
// at this point. If a show callback is not given the item will
// have $(this).show() called on it.
show: function () {
$(this).slideDown();
},
// (Optional)
// "hide" is called when a user clicks on a data-repeater-delete
// element. The item is still visible. "hide" is passed a function
// as its first argument which will properly remove the item.
// "hide" allows for a confirmation step, to send a delete request
// to the server, etc. If a hide callback is not given the item
// will be deleted.
hide: function (deleteElement) {
if (confirm('Are you sure you want to delete this element?')) {
$(this).slideUp(deleteElement);
}
},
// (Optional)
// Removes the delete button from the first list item,
// defaults to false.
isFirstItemUndeletable: true
})
});
</script>
}
我在我的表单中使用 jquery 转发器来动态地仅将输入组的一部分添加到表单中。我确实尝试过,但无法将输入绑定到模型,我失明了。
这是我的模型。
public class SuggestionCreateEditViewModel
{
public Guid[] DetectionId { get; set; }
public SuggestionCreateEditRepeatedModel[] Repeated { get; set; }
}
public class SuggestionCreateEditRepeatedModel
{
public Guid To { get; set; }
public string Description { get; set; }
public DateTime Deadline { get; set; }
}
表格,为了简洁我删除了很多表格部分
<div class="col-lg-9 col-md-9 col-sm-12">
<select asp-for="DetectionId" asp-items="ViewBag.AllDetections" class="m-bootstrap-select m_selectpicker toValidate"
multiple data-actions-box="true" data-width="100%"></select>
</div>
<div class="col-lg-9 col-md-9 col-sm-12 input-group date">
<input name = "Repeated.Deadline" type="text" readonly class="form-control toValidate dtDueDate" />
</div>
<div class="col-lg-12 col-md-12 col-sm-12">
<textarea name = "Repeated.Description" class="form-control toValidate txtSuggestion" type="text" >
</textarea>
</div>
在将新的重复部分添加到表单之后并在将其发布到服务器之前,如果我 form.serailizeArray()
它 returns 集合如下(jquery 表单转发器动态形状名称我相信)
{name: "DetectionId", value: "afca1b82-0455-432e-c780-08d6ac38b012"}
{name: "[0][Repeated.To][]", value: "b1176b82-1c25-4d13-9283-df2b16735266"}
{name: "[0][Repeated.Deadline]", value: "04/04/2019"}
{name: "[0][Repeated.Description]", value: "<p>test 1</p>"}
{name: "[1][Repeated.To]", value: "188806d8-202a-4787-98a6-8dc060624d93"}
{name: "[1][Repeated.Deadline]", value: "05/04/2019"}
{name: "[1][Repeated.Description]", value: "<p>test 2</p>"}
和我的控制器
[HttpPost]
public IActionResult CreateSuggestion(SuggestionCreateEditViewModel model, IFormFile[] documents)
{...
控制器无法绑定 Repeated
,仅绑定了 DetectionId
。我应该如何塑造我的模型来获取数据?
从表面上看,控制器无法将转发器属性绑定回您的视图模型,因为发布内容的命名与您视图模型中的命名不匹配(如 Topher 所述)。
DetectionId 的命名正确,因为 属性 的名称匹配但它不是数组。
要解析数组,我们需要确保在表单中包含 属性 名称以及索引,以便 mvc 模型绑定知道将结果绑定到何处。
这样,您可以尝试将名称的格式更改为: 已重复[0].到
这应该与您的控制器匹配并正确绑定。
有关绑定的更多信息,请参阅this。
这是 jquery.repeater.js
的工作演示,请注意这一行 <div data-repeater-list="Repeated">
,它将像 name="Repeated[0][Description]"
@model TestCore.Models.SuggestionCreateEditViewModel
@{
ViewData["Title"] = "Contact";
}
<form class="repeater" asp-action="CreateSuggestion" method="post">
<!--
The value given to the data-repeater-list attribute will be used as the
base of rewritten name attributes. In this example, the first
data-repeater-item's name attribute would become group-a[0][text-input],
and the second data-repeater-item would become group-a[1][text-input]
-->
<div data-repeater-list="Repeated">
<div data-repeater-item>
<div class="col-lg-9 col-md-9 col-sm-12">
<select asp-for="DetectionId" asp-items="ViewBag.AllDetections" class="m-bootstrap-select m_selectpicker toValidate"
multiple data-actions-box="true" data-width="100%"></select>
</div>
<div class="col-lg-12 col-md-12 col-sm-12">
<textarea name="Description" class="form-control toValidate txtSuggestion" type="text">
</textarea>
</div>
</div>
</div>
<input data-repeater-create type="button" value="Add" />
<input type="submit" value="Submit"/>
</form>
@section Scripts{
<!-- Import repeater js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.repeater/1.2.1/jquery.repeater.js"></script>
<script>
$(document).ready(function () {
$('.repeater').repeater({
// (Optional)
// start with an empty list of repeaters. Set your first (and only)
// "data-repeater-item" with style="display:none;" and pass the
// following configuration flag
initEmpty: true,
// (Optional)
// "show" is called just after an item is added. The item is hidden
// at this point. If a show callback is not given the item will
// have $(this).show() called on it.
show: function () {
$(this).slideDown();
},
// (Optional)
// "hide" is called when a user clicks on a data-repeater-delete
// element. The item is still visible. "hide" is passed a function
// as its first argument which will properly remove the item.
// "hide" allows for a confirmation step, to send a delete request
// to the server, etc. If a hide callback is not given the item
// will be deleted.
hide: function (deleteElement) {
if (confirm('Are you sure you want to delete this element?')) {
$(this).slideUp(deleteElement);
}
},
// (Optional)
// Removes the delete button from the first list item,
// defaults to false.
isFirstItemUndeletable: true
})
});
</script>
}