2010-05-28 11 views
7

Ich benutze Steve Sandersons BeginCollectionItem helper mit ASP.NET MVC 2 zu modellieren binden eine Sammlung wenn Elemente.Modellbindung verschachtelte Sammlungen in ASP.NET MVC

Das funktioniert gut, solange das Modell der Sammlungselemente keine andere Sammlung enthält.

ich ein Modell wie dieses:

-Produkt
--Variants
--- IncludedAttributes

Wann immer ich machen und das Modell der Varianten Sammlung binden, funktioniert es jusst in Ordnung. Aber mit der IncludedAttributes Sammlung, kann ich den BeginCollectionItem Helfer nicht, weil die ID und Namen Wert wird nicht die ID und Namen Wert ehren, die für seine Eltern Variant produziert wurde:

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

Wenn man sich die Namen der ersten versteckten Feld innerhalb der Tabelle, es ist Variants.IncludedAttributes - wo es hätte sein sollen Variants [bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126] .IncludedAttributes [0]

Das ist, weil, wenn ich rufe BeginCollectionItem das zweite Mal (In der IncludedAttributes-Auflistung) gibt es keine Informationen über den Elementindexwert der übergeordneten Variant.

Mein Code eine Variante für die Darstellung dieser wie folgt aussieht:

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

und der Code zur Wiedergabe eines 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> 
<% } %> 

Antwort

6

Wie Sie MVC 2 und EditorFor verwenden, sollten Sie nicht brauchen Steve's Lösung zu benutzen, die ich glaube, ist nur eine Arbeit für MVC 1. Sie sollten nur in der Lage sein, etwas zu tun:

Bitte beachten Sie, dass die Verwendung der Indizes ... [i] ... [j] ... wichtig ist und MVC weiß, wie die IDs und Namen korrekt dargestellt werden.

+8

Oh, habe vergessen, ein Detail zu erzählen. Ich nahm das als selbstverständlich, seit ich Steve's Blogpost gelesen habe. Das Problem ist, dass Javascript verwendet, um neue Elemente zu injizieren - der Wert von i und j kommt aus der Synchronisation. Das ist das Schlaue an Steves Lösung, denn es macht einen Guid, der nicht in Ordnung sein muss. Es ist also nicht (nur) ein Workaround für MVC 1. – MartinHN

Verwandte Themen