2013-05-12 4 views
2

Я пытаюсь перебирать многоуровневые динамические меню. Мне удалось сделать это вручную каждый раз, если вы хотите отобразить дочерний элемент Menus его родительского элемента, мне нужно выполнить цикл вручную. Я хотел бы знать лучший способ или альтернативу циклического многоуровневого управления этими динамическими меню Вот что я сделал до сих пор;Loop Through Многоуровневые динамические меню в Asp.Net MVC

@{ var menusList = ViewBag.Menus as IEnumerable<ParentMenuViewModel>; } 
@foreach (var parentMenu in menusList.Where(p => p.ParentId == 0)) 
{ 
    <ul> 
     <li> 
      <h1>@parentMenu.Name</h1> 
      @if (menusList.Count(p => p.ParentId == parentMenu.MenuId) > 0) 
      { 
       <ul> 
        @foreach (var childMenu in menusList.Where(p => p.ParentId == parentMenu.MenuId)) 
        { 
         <h2>@childMenu.Name</h2> 
         if (menusList.Count(p => p.ParentId == childMenu.MenuId) > 0) 
         { 
          foreach (var subChild in menusList.Where(p => p.ParentId == childMenu.MenuId)) 
          { 
           <h3>@subChild.Name</h3> 
          } 
         } 
        } 
       </ul> 
      } 
     </li> 
    </ul> 

} 

UPDATE: Вывод выглядит следующим образом;

HOME 
SUB MENU1 
    SUB SUB MENU1 
    SUB SUB MENU2 

Однако у меня в моей базе есть что-то подобное;

HOME 
SUB MENU1 
    SUB SUB MENU1 
    SUB SUB MENU2 
    Sub SUB SUB MENU1 
    Sub SUB SUB MENU2 

Это моя модель;
enter image description here

ответ

5

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

ViewModel

// The ViewModel is now a hirearchical model, where each item has a list of children. 
public class MenuViewModel 
{ 
    int MenuId {get; set;} 
    string Name {get; set;} 
    //other properties 
    ** snip ** 
    List<MenuViewModel> Children {get; set;} 
} 

Контроллер

Transform модель в иерархической ViewModel:

public ActionResult Menus(){ 
    List<Menu> menusource; // get your menus here 
    ViewBag.Menus = CreateVM(0, menusource); // transform it into the ViewModel 
    return View(); 
} 

public IEnumerable<MenuViewModel> CreateVM(int parentid, List<Menu> source) 
{ 
    return from men in source 
      where men.ParentId = parentid 
      select new MenuViewModel(){ 
         MenuId = men.MenuId, 
         Name = men.Name 
         // other properties 
         Children = CreateVM(men.MenuId, source) 
        }; 
} 

View

@{ 
    var menusList = ViewBag.Menus as IEnumerable<MenuViewModel>; 
    Html.RenderPartial("MenuPartial", menuslist); 
} 

MenuPartial

@model IEnumerable<MenuViewModel> 

@foreach (var menuitem in model) 
{ 
    <ul> 
     <li> 
      <h1>@menuitem.Name</h1> 
      @{ 
       Html.RenderPartial("MenuPartial", menuitem.Children); 
      } 
     </li> 
    </ul> 
} 

Единственное, что вам будет не хватать здесь в отношении исходного кода является то, что вы не имеете различные HX-теги, но вы могли бы найти способ вокруг этого, создавая еще одну модель обзора и передавая ей уровень, на котором вы сейчас находитесь.

Примечание: Я набрал весь этот код в SO-редакторе, поэтому могут возникнуть небольшие синтаксические ошибки.

+1

изменен в зависимости от моей потребности, и это сработало. Спасибо –

+0

вы можете сделать его asycronous (ваш код). я пытался, но не добился успеха. Использование async и ожидание ключевых слов –