Создание списка категорий и подкатегорий с помощью asp.net mvc2

У меня такое чувство, что я делаю это ужасно, ужасно неправильно. Вложенные циклы for? Каков наилучший метод перечисления подкатегорий? У меня есть ощущение, что это включает в себя подготовку списка в моем действии контроллера и отправку его клиенту через некоторый результат действия, но я не знаю, с чего начать? Кто-нибудь может указать мне правильное направление? Вот мой хакерский код:

 <h2>Categories</h2>
    <a href="javascript:;" onclick="newCategory()">Create New Category</a>
<br />
    <ul class="parent">
        <%foreach (var category in Model.Categories){%>
            <%-- List all of the top-level parent categories --%>
            <%if (category.IsParent && category.ParentId == 0)%>
            <li>
                <span class="buttons"><a href="javascript:;" onclick="editCategory(<%:category.CategoryId%>)" class="edit"></a> <a href="javascript:;" onclick="deleteCategory(<%:category.CategoryId%>)" class="delete"></a></span>
                <span class="categoryName"><%:category.CategoryName%></span>
                <span class="positionButtons"><%:Html.ActionLink(" ", "MoveCategoryUp", new {id = category.CategoryId},
                                                new {Class = "moveUp"})%><%:Html.ActionLink(" ", "MoveCategoryDown", new {id = category.CategoryId},
                                                new {Class = "moveDown"})%></span>
                <%-- List all of the subs for each parent --%>

                    <ul>
<%-- Level 1 --%>       <%foreach (var sub1 in Model.Categories){%>
                            <%if (sub1.ParentId == category.CategoryId){%>
                                <li>
                                    <span class="buttons"><a href="javascript:;" onclick="editCategory(<%:sub1.CategoryId%>)" class="edit"></a> <a href="javascript:;" onclick="deleteCategory(<%:sub1.CategoryId%>)" class="delete"></a></span>
                                    <span class="categoryName"><%:category.CategoryName%></span>
                                    <span class="positionButtons"><%:Html.ActionLink(" ", "MoveCategoryUp", new {id = sub1.CategoryId},new {Class = "moveUp"})%><%:Html.ActionLink(" ", "MoveCategoryDown", new {id = sub1.CategoryId},new {Class = "moveDown"})%></span>

                                    <%-- List all of the subs for each parent --%>
                                    <%if (sub1.IsParent){%>
                                    <ul>
<%-- Level 2 --%>                       <%foreach (var sub2 in Model.Categories){%>
                                            <%if (sub2.ParentId == sub1.CategoryId){%>
                                                <li>
                                                    <span class="buttons"><a href="javascript:;" onclick="editCategory(<%:sub2.CategoryId%>)" class="edit"></a> <a href="javascript:;" onclick="deleteCategory(<%:sub2.CategoryId%>)" class="delete"></a></span>
                                                    <span class="categoryName"><%:category.CategoryName%></span>
                                                    <span class="positionButtons"><%:Html.ActionLink(" ", "MoveCategoryUp", new {id = sub2.CategoryId},new {Class = "moveUp"})%><%:Html.ActionLink(" ", "MoveCategoryDown", new {id = sub2.CategoryId},new {Class = "moveDown"})%></span>
                                                    <%-- List all of the subs for each parent --%>
                                                    <%if (sub2.IsParent){%>
                                                    <ul>
<%-- Level 3 --%>                                       <%foreach (var sub3 in Model.Categories){%>
                                                            <%if (sub3.ParentId == sub2.CategoryId){%>
                                                                <li>
                                                                    <span class="buttons"><a href="javascript:;" onclick="editCategory(<%:sub3.CategoryId%>)" class="edit"></a> <a href="javascript:;" onclick="deleteCategory(<%:sub3.CategoryId%>)" class="delete"></a></span>
                                                                    <span class="categoryName"><%:category.CategoryName%></span>
                                                                    <span class="positionButtons"><%:Html.ActionLink(" ", "MoveCategoryUp",new {id = sub3.CategoryId},new {Class = "moveUp"})%><%:Html.ActionLink(" ", "MoveCategoryDown",new {id = sub3.CategoryId},new {Class = "moveDown"})%></span>

                                                                     <%-- List all of the subs for each parent --%>
                                                                    <%if (sub3.IsParent){%>
                                                                    <ul>
<%-- Level 4 --%>                                                       <%foreach (var sub4 in Model.Categories){%>
                                                                            <%if (sub4.ParentId == sub3.CategoryId){%>
                                                                                <li>
                                                                                    <span class="buttons"><a href="javascript:;" onclick="editCategory(<%:sub4.CategoryId%>)" class="edit"></a> <a href="javascript:;" onclick="deleteCategory(<%:sub4.CategoryId%>)" class="delete"></a></span>
                                                                                    <span class="categoryName"><%:category.CategoryName%></span>
                                                                                    <span class="positionButtons"><%:Html.ActionLink(" ", "MoveCategoryUp", new {id = sub4.CategoryId}, new {Class = "moveUp"})%><%:Html.ActionLink(" ", "MoveCategoryDown", new {id = sub4.CategoryId}, new {Class = "moveDown"})%></span>

                                                                                    <%-- If more than 4 levels of subcategories are required, put another level here --%>
                                                                                </li>
                                                                            <%}%>
                                                                        <%}%>
                                                                    </ul>
                                                                    <%}%>
                                                                </li>
                                                            <%}%>
                                                        <%}%>
                                                    </ul>
                                                    <%}%>
                                                </li>
                                            <%}%>
                                        <%}%>
                                    </ul>
                                    <%}%>
                                </li>
                            <%}%>
                        <%}%>
                    </ul>
            </li>

        <%}%>

    </ul>

Изменить

К сожалению, этот код не отображает результаты, которые я ищу, поэтому я не могу предоставить больше, чем это: http://jsfiddle.net/EeaGr/ В каждом элементе списка есть кнопки для редактирования / удаления и перемещения вверх / вниз для его категории. Моя категория имеет следующие свойства:

CategoryID: int

Имя: строка

ParentID: int

IsParent: bool

Должность: int


person Grahame A    schedule 24.09.2010    source источник
comment
Святая Богородица.   -  person Darin Dimitrov    schedule 25.09.2010
comment
Мне трудно представить себе результат этого! Есть ли шанс предоставить визуализированное представление HTML в jsfiddle.net ?? Вы также можете добавить CSS, чтобы мы могли видеть, что вы видите на странице   -  person DaveDev    schedule 25.09.2010
comment
Лол, 2 года спустя, и я смотрю на это, я могу только повторить то, что сказал Дарин ... Святая Богородица ... о чем я думала?   -  person Grahame A    schedule 04.01.2013


Ответы (1)


Во-первых, я бы изменил структуру категорий, чтобы у каждого Category было свойство Subcategories.

Затем вы должны создать пользовательский элемент управления, который отображает одну Category, и если в этой категории есть подкатегории, она вызывает себя рекурсивно:

CategoryControl.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Category>" %>
<%@ Import Namespace="so_subcats.Model" %>
<li><%= Model.Name %>
    <% if (Model.Subcategories != null) { %>
        <ul>
        <% foreach (Category subcat in Model.Subcategories)
             Html.RenderPartial("CategoryControl", subcat); %>
        </ul>
    <% } %>
</li>

Затем просто создайте представление, которое отображает этот элемент управления для каждой из категорий верхнего уровня:

Categories.aspx:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
  Inherits="System.Web.Mvc.ViewPage<IEnumerable<Category>>" %>
<%@ Import Namespace="so_subcats.Model" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Categories
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>Categories</h2>
        <ul>
        <% foreach (Category cat in Model)
             Html.RenderPartial("CategoryControl", cat); %>
        </ul>

</asp:Content>

Конечно, если вы не хотите изменять структуру своих классов, вы также можете использовать это решение, вам просто нужно немного его изменить.

person svick    schedule 24.09.2010
comment
Могу ли я добавить это свойство на уровне базы данных или в моем классе модели? - person Grahame A; 25.09.2010
comment
В вашей модели. Это другой конец отношения «один ко многим», представленного ParentId в БД (вам, вероятно, следует изменить его на Parent, чтобы он ссылался на родительский объект в вашей модели). - person svick; 25.09.2010
comment
+1 Я бы тоже пошел по этому пути или имел бы специальный помощник html, который запускал бы рекурсивный метод. то же самое, что и выше, только что сделано внутри представления, а не модели (или в этом случае я бы поместил это в модель задачи) - person jim tollan; 25.09.2010