2010-05-28 6 views
7

J'utilise BeginCollectionItem helper de Steve Sanderson avec ASP.NET MVC 2 pour modéliser lier une collection si des éléments.Modèle de liaison des collections imbriquées dans ASP.NET MVC

Cela fonctionne correctement, tant que le modèle des éléments de collection ne contient pas d'autre collection.

J'ai un modèle comme celui-ci:

-Product
--Variants
--- IncludedAttributes

Chaque fois que je rends et le modèle lie la collection Variantes, il fonctionne très bien jusst. Mais avec la collection IncludedAttributes, je ne peux pas utiliser l'aide BeginCollectionItem parce que l'identifiant et la valeur des noms ne respectera pas l'identifiant et la valeur des noms qui a été produit pour c'est la variante mère:

<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 vous regardez le nom du premier champ caché à l'intérieur de la table, il est Variants.IncludedAttributes - où il aurait dû être Variants [bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126] .IncludedAttributes [...] ...

C'est parce que quand j'appelle BeginCollectionItem la deuxième fois (Dans la collection IncludedAttributes), aucune information sur la valeur d'index de l'élément de la variable parent n'est fournie.

Mon code pour rendre une variante ressemble à ceci:

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

Et le code pour rendre un 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> 
<% } %> 

Répondre

6

Comme vous utilisez MVC 2 et EditorFor, vous ne devriez pas avoir besoin pour utiliser la solution de Steve, qui je crois est juste un travail autour de MVC 1. Vous devriez juste être en mesure de faire quelque chose comme:

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

Veuillez noter que l'utilisation des index ... [i] ... [j] ... est importante et c'est ainsi que MVC saura rendre les ID et les noms correctement.

+8

Oh, j'ai oublié de dire un détail. J'ai pris cela pour acquis, depuis que j'ai lu l'article de Steve. Le problème est, qu'en utilisant javascript pour injecter de nouveaux éléments - la valeur de i et j est désynchronisée. C'est la chose intelligente à propos de la solution de Steve, car elle rend un Guid qui n'a pas besoin d'être en ordre. Donc, ce n'est pas (seulement) une solution de contournement pour MVC 1. – MartinHN

Questions connexes