1 回答
TA贡献2003条经验 获得超2个赞
你的问题是部分呈现基于单个AdminProductDetailModel
对象的html ,但你试图回发一个集合。当您动态地添加一个新的对象,你继续增加,看起来像重复控制<input name="productTotalQuantity" ..>
(这也创造因为重复的无效的HTML id
属性),其中作为他们需要<input name="[0].productTotalQuantity" ..>
,<input name="[1].productTotalQuantity" ..>
等等,以绑定到一个集合上回发。
的DefaultModelBinder
要求,对于藏品的索引从零开始,并是连续的,或者表单值包括Index=someValue
其中P是someValue
(例如<input name="[ABC].productTotalQuantity" ..><input name="Index" value="ABC">
,这在菲尔哈克的文章中详细解释模型绑定到一个列表。使用索引方法通常更好,因为它还允许您从列表中删除项目(否则,有必要重命名所有现有控件,以便索引器是连续的)。
两种可能的解决方法。
选项1
对部分视图使用BeginItemCollection帮助器。此帮助程序将Index
基于GUID 呈现值的隐藏输入。您需要在局部视图和渲染现有项目的循环中使用它。你的部分看起来像
@model IKLE.Model.ProductModel.AdminProductDetailModel@using(Html.BeginCollectionItem()) { <div class="editor-field"> @Html.LabelFor(model => model.fkConfigChoiceCategorySizeId) @Html.DropDownListFor(model => model.fkConfigChoiceCategorySizeId, Model.sizeList, "--Select Size--") @Html.ValidationMessageFor(model => model.fkConfigChoiceCategorySizeId) </div> ....}
选项2
手动创建表示具有“假”索引器的新对象的html元素,将它们放在隐藏容器中,然后在“添加”按钮事件中,克隆html,更新索引器和索引值,并将克隆元素附加到DOM。要确保html正确,请在for
循环中创建一个默认对象并检查它生成的html。此答案中显示了此方法的一个示例
<div id="newItem" style="display:none"> <div class="editor-field"> <label for="_#__productTotalQuantity">Quantity</label> <input type="text" id="_#__productTotalQuantity" name="[#].productTotalQuantity" value /> .... </div> // more properties of your model</div>
注意使用'假'索引器来防止这个被绑定在帖子后面('#'和'%'不匹配,所以它们会被忽略DefaultModelBinder
)
$('#addField').click(function() { var index = (new Date()).getTime(); var clone = $('#NewItem').clone(); // Update the indexer and Index value of the clone clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']')); clone.html($(clone).html().replace(/"%"/g, '"' + index + '"')); $('#yourContainer').append(clone.html());}
选项1的优点是您强烈键入模型的视图,但这意味着每次添加新项目时都要调用服务器。选项2的优点是它全部完成了客户端,但如果你对模型进行任何更改(例如向属性添加验证属性),那么你还需要手动更新html,使维护更加困难。
最后,如果您正在使用客户端验证(jquery-validate-unobtrusive.js),那么每次向DOM添加新元素时都需要重新解析验证器,如本答案中所述。
$('form').data('validator', null);$.validator.unobtrusive.parse($('form'));
当然,您需要更改POST方法以接受集合
[HttpPost]public ActionResult AddDetail(IEnumerable<AdminProductDetailModel> model){ ....}
- 1 回答
- 0 关注
- 581 浏览
添加回答
举报