代码之家  ›  专栏  ›  技术社区  ›  stoic Kobus Kleynhans

基于父子类的视图层次菜单

  •  0
  • stoic Kobus Kleynhans  · 技术社区  · 14 年前

    public class Page
    {
        public int Id { get; set; }
        public Page Parent { get; set; }
        public string Name { get; set; }
        public string Title { get; set; }
    }
    

    我正在将该模型传递给一个视图,需要基于该模型创建一个层次菜单:

    <ul>
        <li>Page
            <ul>
                <li>Sub Page</li>
            </ul>
        </li>
    

    我可以在我的控制器中创建标记,但这不利于测试。

    有什么想法吗?

    1 回复  |  直到 14 年前
        1
  •  1
  •   Manaf Abu.Rous    14 年前

    public class MenuItem
    {
        public int MenuID { get; set; }
        public int ID { get; set; }
        public String Label { get; set; }
        public String Link { get; set; }
        public Boolean Show { get; set; }
    
        public MenuItem(int menuId, int id, string label, string link, Boolean show)
        {
            this.MenuID = menuId;
            this.ID = id;
            this.Label = label;
            this.Link = link;
            this.Show = show;
        }
    }
    

    //

    public class Menu
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public List<MenuItem> MenuItems { get; set; }
    
        public Menu(int id, string name)
        {
            this.ID = id;
            this.Name = name;
            this.MenuItems = new List<MenuItem>();
        }
    
    }
    

    public class NavigationModel
    {
        public int currentMenuID { get; set; }   
        // used to determine the current displayed Menu to add
        // the "current" class to it. (to be set in the controller)
    
        public int currentMenuItemID { get; set; } 
        // used to determine the current displayed MenuItem to add
        // the "current" class to it. (to be set in the controller)
    
        public List<Menu> Menus { get; set; }
    
    
        public NavigationModel()
        {
            this.Menus = new List<Menu>();
            // Set Default Menu ( Menu 1 )
            this.currentMenuID = 1;
            // Set Default Menau Item ( None )
            this.currentMenuItemID = 0;
        }
    }
    

    private static NavigationModel BuildNavigationMenu(User currentUser, string rootURL)
        {
            string loginURL = rootURL + "Account/LogOn";
    
            // Main Menu
            Menu MainMenu = new Menu(1, "Home");
            MainMenu.MenuItems.Add(new MenuItem(1, 1, "Welcome", rootURL, true));
            MainMenu.MenuItems.Add(new MenuItem(1, 2, "How It Works", rootURL + "Home/HowDoesItWork", true));
    
            // Work Menu
            Menu WorkMenu = new Menu(2, "Work");
            WorkMenu.MenuItems.Add(new MenuItem(2, 1, "Profile", rootURL + "User/Profile/" + currentUser.ID , true));
            WorkMenu.MenuItems.Add(new MenuItem(2, 2, "Customers", "#", true));
    
            // Add Menus To Navigation Model
            NavigationModel navigationMenu = new NavigationModel();
            navigationMenu.Menus.Add(MainMenu);
            navigationMenu.Menus.Add(HireMenu);
    
            return navigationMenu;
    }
    

    //我有一个NavigationHelper,它负责用以下两种方法输出HTML。

    注意:(这是一个简化的版本,因为在我的实现中,我使用Menu&the MenuItem的id来定位当前显示的菜单,并向其中添加“current”CSS类)

    public static string DisplayMenu(this HtmlHelper helper, NavigationModel navigationMenu)
    { 
        public static string DisplayMenu(this HtmlHelper helper, NavigationModel navigationMenu)
        {            
            String result = "<ul id='main-nav'>\n";
            foreach(Menu menu in navigationMenu.Menus)
            {
                result +=     "<li>\n";
                result +=         string.Format("<a href='#'> {0} </a>\n",helper.AttributeEncode(menu.Name));
                result +=         "<ul>\n";
                foreach(MenuItem item in menu.MenuItems)
                {
                    result += NavigationHelper.ConvertToItem(helper, item);
                }
                result +=         "</ul>\n";
                result +=     "</li>\n";
            }
            result +=     "</ul>\n";
    
            return result;
        }
    
        private static string ConvertToItem(this HtmlHelper helper,MenuItem item)
        {
            if (item.Show)
            {
                return string.Format("<li><a href='{0}'>{1}</a></li>\n", helper.AttributeEncode(item.Link), helper.AttributeEncode(item.Label));
            }
            else { return ""; }   
        }
    }
    

    <!-- Navigation -->
    <%= Html.DisplayMenu(Model.NavigationMenu) %>
    

    注意:我有一个类型为(BaseViewModel)的强类型母版页,它包含类型为NavigationModel的属性NavigationMenu

    对我来说,我发现有一个强类型的母版页,使事情更容易和更干净。王尔德有一个很好的方法来实现他们在他的 GolfTracker Series