2010-05-28 91 views
7

我正在使用Steve Sanderson的BeginCollectionItem helper和ASP.NET MVC 2來建模綁定一個集合,如果項目。ASP.NET MVC中的模型綁定嵌套集合

工作正常,只要收集項目的模型不包含另一個集合。

我有這樣一個模型:

- 產品
--Variants
--- IncludedAttributes

每當我渲染和模型結合的變體集合,它的工作原理jusst罰款。但隨着IncludedAttributes收集,我不能使用BeginCollectionItem幫手,因爲ID和名稱值不會兌現ID和名稱值是因爲它產生的是父變:

<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集合上)沒有提供關於其父變體的項目索引值的信息。

我對渲染變異代碼如下所示:

<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> 
<% } %> 

回答

6

當你使用MVC 2和EditorFor,你不應該需要使用史蒂夫的解決方案,我相信這只是解決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和名稱。

+8

哦,忘了告訴一個細節。我認爲這是理所當然的,因爲我讀過史蒂夫的博客文章。 問題是,使用JavaScript注入新項目 - 我和j的價值不同步。這是史蒂夫解決方案的聰明之處,因爲它呈現了一個不需要按順序排列的Guid。所以這不是(僅)MVC 1的解決方法。 – MartinHN 2010-05-29 18:06:04