Модель связывания вложенных коллекций в ASP.NET MVC - PullRequest
7 голосов
/ 28 мая 2010

Я использую помощник Стива Сандерсона BeginCollectionItem с ASP.NET MVC 2 для моделирования привязки коллекции, если элементы.

Это прекрасно работает, если Модель элементов коллекции не содержит другой коллекции.

У меня есть такая модель:

-Продукт
--Variants
--- IncludedAttributes

Всякий раз, когда я рендерил и связывал модель коллекции Variants, она работает просто отлично. Но с коллекцией IncludedAttributes я не могу использовать помощник BeginCollectionItem, потому что значение id и names не будет соответствовать значению 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 - там, где это должны быть варианты [bbd4fdd4-fa22-49f9-8a5e-3ff7e2942126] .IncludedAttributes [...] .. .

Это потому, что когда я вызываю BeginCollectionItem во второй раз (в коллекции IncludedAttributes), не предоставляется никакой информации о значении индекса элемента его родительского варианта.

Мой код для рендеринга 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>

И код для рендеринга включенного атрибута:

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

1 Ответ

6 голосов
/ 29 мая 2010

Поскольку вы используете 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 будет знать, как правильно отображать идентификаторы и имена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...