2010-05-28 25 views
7

Estoy usando BeginCollectionItem helper de Steve Sanderson con ASP.NET MVC 2 para modelar una colección de elementos.Colecciones anidadas de encuadernación de modelos en ASP.NET MVC

Eso funciona bien, siempre que el Modelo de los elementos de la colección no contenga otra colección.

Tengo un modelo como este:

-Producto
--Variants
--- IncludedAttributes

Siempre que se haga y modelo de obligar a la colección de variantes, funciona jusst bien. Pero con la colección IncludedAttributes, no puedo usar el ayudante BeginCollectionItem debido a que el valor de ID y los nombres no aceptará el valor de ID y los nombres que se produjo por su variante padres:

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

Si nos fijamos en el nombre de la primer campo oculto dentro de la tabla, es Variants.IncludedAttributes - donde debería haber sido variantes [bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126] .IncludedAttributes [...] ...

Eso es porque cuando llamo BeginCollectionItem la segunda vez (En la colección IncludedAttributes) no se proporciona información sobre el valor de índice de elemento de su variante principal.

Mi código para la representación de una variante se ve así:

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

y el código para emitir una 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> 
<% } %> 

Respuesta

6

Como está utilizando MVC 2 y EditorFor, no debería necesitar para usar la solución de Steve, que creo que es solo una solución para MVC 1. Simplemente debería ser capaz de hacer algo como:

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

Tenga en cuenta que el uso de los índices ... [i] ... [j] ... es importante y es cómo MVC sabrá cómo representar los Id y los nombres correctamente.

+8

Ah, se olvidó de decir un detalle. Lo di por sentado, desde que leí la publicación del blog de Steve. El problema es que al usar javascript para inyectar nuevos elementos, el valor de i y j no se sincroniza. Eso es lo inteligente de la solución de Steve, ya que representa un Guid que no necesita estar en orden. Entonces, no es (solo) una solución para MVC 1. – MartinHN

Cuestiones relacionadas