我正在使用Steve Sanderson的
BeginCollectionItem helper和ASP.NET MVC 2模拟绑定项目的集合.
只要集合项的模型不包含其他集合,这样就可以了.
我有这样的模型:
-产品
–Variants
— IncludedAttributes
每当我渲染和模型绑定Variants集合时,它都可以正常工作.但是使用IncludedAttributes集合,我无法使用BeginCollectionItem帮助器,因为id和names值将不会遵循为其父Variant生成的id和names值:
<div class="variant"> <input type="hidden" value="bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126" autocomplete="off" name="Variants.index"> <input type="hidden" value="0" name="Variants[bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126].SlotAmount" id="Variants_bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126__SlotAmount"> <table class="included-attributes"> <input type="hidden" value="0" name="Variants.IncludedAttributes[c5989db5-b1e1-485b-b09d-a9e50dd1d2cb].Id" id="Variants_IncludedAttributes_c5989db5-b1e1-485b-b09d-a9e50dd1d2cb__Id" class="attribute-id"> <tr> <td> <input type="hidden" value="0" name="Variants.IncludedAttributes[c5989db5-b1e1-485b-b09d-a9e50dd1d2cb].Id" id="Variants_IncludedAttributes_c5989db5-b1e1-485b-b09d-a9e50dd1d2cb__Id" class="attribute-id"> </td> </tr> </table> </div>
如果你查看表格中第一个隐藏字段的名称,它就是Variants.IncludedAttributes – 它应该是Variants [bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126] .IncludedAttributes […] …
这是因为当我第二次调用BeginCollectionItem时(在IncludedAttributes集合上),没有给出关于它的父Variant的项索引值的信息.
我渲染Variant的代码如下所示:
<div class="product-variant round-content-Box grid_6" data-id="<%: Model.AttributeType.Id %>"> <h2><%: Model.AttributeType.AttributeTypeName %></h2> <div class="Box-content"> <% using (Html.BeginCollectionItem("Variants")) { %> <div class="slot-amount"> <label class="inline" for="slotAmountSelectList"><%: Text.amountOfThisVariant %>:</label> <select id="slotAmountSelectList"><option value="1">1</option><option value="2">2</option></select> </div> <div class="add-values"> <label class="inline" for="txtProductAttributeSearch"><%: Text.addVariantItems %>:</label> <input type="text" id="txtProductAttributeSearch" class="product-attribute-search" /><span><%: Text.or %> <a class="select-from-list-link" href="#select-from-list" data-id="<%: Model.AttributeType.Id %>"><%: Text.selectFromList.ToLowerInvariant() %></a></span> <div class="clear"></div> </div> <%: Html.HiddenFor(m=>m.SlotAmount) %> <div class="included-attributes"> <table> <thead> <tr> <th><%: Text.name %></th> <th style="width: 80px;"><%: Text.price %></th> <th><%: Text.shipping %></th> <th style="width: 90px;"><%: Text.image %></th> </tr> </thead> <tbody> <% for (int i = 0; i < Model.IncludedAttributes.Count; i++) { %> <tr><%: Html.EditorFor(m => m.IncludedAttributes[i]) %></tr> <% } %> </tbody> </table> </div> <% } %> </div> </div>
以及用于呈现IncludedAttribute的代码:
<% using (Html.BeginCollectionItem("Variants.IncludedAttributes")) { %> <td> <%: Model.AttributeName %> <%: Html.HiddenFor(m => m.Id,new { @class = "attribute-id" })%> <%: Html.HiddenFor(m => m.ProductAttributeTypeId) %> </td> <td><%: Model.Price.ToCurrencyString() %></td> <td><%: Html.DropDownListFor(m => m.requiredShippingTypeId,AppData.GetShippingTypesSelectListItems(Model.requiredShippingTypeId)) %></td> <td><%: Model.ImageId %></td> <% } %>
解决方法
当你使用MVC 2和EditorFor时,你不应该使用Steve的解决方案,我认为这只是解决MVC 1的问题.你应该能够做到这样的事情:
<% for (int i = 0; i < Model.Variants.Count; i++) { %> <%= Html.DisplayFor(m => m.Variants[i].AttributeType.AttributeTypeName) %> <% for (int j = 0; j < Model.Variants[i].IncludedAttributes.Count; j++) { %> <%= Html.EditorFor(m => m.Variants[i].IncludedAttributes[j]) %> <% } %> <% } %>
请注意,使用索引… [i] … [j] …很重要,MVC将如何正确地呈现Id和名称.