Bootstrap Metronic 学习记录(二)菜单栏

这篇博客记录了使用Bootstrap Metronic框架构建后台管理系统的菜单栏过程,包括环境配置(VS2013+MVC5.0+EF6.1+SQLServer2012),数据库和表的创建,页面布局的提取,特别是动态生成无限级别菜单的实现方法,通过递归读取数据拼接HTML。虽然没有提供Ajax模式,但作者通过读取数据表实现了菜单的动态生成。
摘要由CSDN通过智能技术生成

1.简介

1)  .环境配置

2)  .提取页面

2).动态生成菜单(无限级别树)

2.系统环境配置

项目需要程序数据支撑,这里选择MVC5.0+EF6.0[SQLSERVER](不对MVC架构和SQLServer做出解读)

运行环境:VS2013+MVC5.0+EF6.1+SQLServer2012

解决方案名称:AppSolution 项目名称:App.Web(UI层)与App.Models(数据访问层) -直接访问模式

提取theme下的所有文件到MVC的Content,提取admin的index.html到_Layout.cshtml来准备改造

 

3.创建数据库和表

数据库:AppDataBase

创建以下数据表,并创建AppDB.edmx

复制代码
USE [AppDataBase]
GO

/****** Object:  Table [dbo].[SysModule]    Script Date: 2015/9/15 21:03:39 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[SysModule](
    [ID] [varchar](50) NOT NULL,        --主键ID
    [Name] [varchar](50) NOT NULL,        --菜单名称
    [ParentID] [varchar](50) NULL,        --上级ID
    [Url] [varchar](200) NULL,            --URL
    [Iconic] [varchar](200) NULL,        --图标
    [Sort] [int] NULL,                    --排序
    [Enable] [bit] NOT NULL,            --是否显示
    [CreateTime] [datetime] NULL,        --创建时间
    [IsLast] [bit] NOT NULL                --是否最后一项
 CONSTRAINT [PK_SysModule] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[SysModule]  WITH NOCHECK ADD  CONSTRAINT [FK_SysModule_SysModule] FOREIGN KEY([ParentID])
REFERENCES [dbo].[SysModule] ([Id])
GO

ALTER TABLE [dbo].[SysModule] NOCHECK CONSTRAINT [FK_SysModule_SysModule]
GO
复制代码

人为造点数据

复制代码
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('0','root','root','Index','icon-settings',NULL,0,NULL,0)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('1','一级菜单01','0','Index','icon-settings',NULL,0,NULL,0)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('11','二级菜单01-01','1','Index','icon-settings',NULL,0,NULL,0)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('111','三级菜单01-01-01','11','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('112','三级菜单01-01-02','11','Index','icon-settings',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('12','二级菜单01-02','1','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('13','二级菜单01-03','1','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('2','一级菜单02','0','Index','icon-settings',NULL,0,NULL,0)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('21','二级菜单02-01','2','Index','icon-settings',NULL,0,NULL,0)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('211','三级菜单02-01-01','5','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('212','三级菜单02-01-02','5','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('22','二级菜单02-02','2','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('23','二级菜单02-03','2','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('3','一级菜单03','0','Index','icon-settings',NULL,0,NULL,0)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('31','二级菜单03-01','3','Index','icon-settings',NULL,0,NULL,0)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('311','三级菜单03-01-01','31','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('312','三级菜单03-01-02','31','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('32','二级菜单03-02','3','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('33','二级菜单03-03','3','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('4','一级菜单04','0','Index','icon-settings',NULL,0,NULL,0)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('41','二级菜单04-01','4','Index','icon-link',NULL,0,NULL,1)
INSERT INTO [SysModule] ([ID],[Name],[ParentID],[Url],[Iconic],[Sort],[Enable],[CreateTime],[IsLast]) values ('42','二级菜单04-02','4','Index','icon-link',NULL,0,NULL,1)

(22 行受影响)
复制代码

 

4.提取页面重要布局

我们是后台系统所以我们保留top. left menu和foot3个部分

我已经提取好了,请复制

  Layout.cshtml

 

再次提取菜单代码

  Menu

大约在466行-529行

分析上面html可以看出,li包含ul循环调用。所以我们用递归读取菜单

5.拼接菜单栏

创建Home视图Index.cshtml并应用_Layout.cshtml

Bootstrap Metronic并菜单没有提供Ajax模式,我们只能读取数据拼接HTML

过程:读取数据表数据递归调用

复制代码
using App.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Text;
namespace App.Web.Controllers
{
    public class HomeController : Controller
    {
        AppDBContainer db = new AppDBContainer();
        public ActionResult Index()
        {

            List<SysModule> menus = db.SysModule.AsQueryable().Where(a=>a.ParentID=="0").ToList();
            StringBuilder sb = new StringBuilder();
            int count = 0;
            bool firstFlag = true;//第一个默认展开
            foreach(var m in menus)
            {
                IQueryable<SysModule> menusChild = db.SysModule.AsQueryable().Where(a => a.ParentID == m.ID);//一级菜单
                count = menusChild.Count();
                sb.AppendFormat("<li class='{0}'>",firstFlag?"start active open":"");
                sb.AppendFormat("<a href='{0}'><i class='{1}'></i><span class='title'>{2}</span><span class='arrow '></span></a>",count>0?"javascript:;":m.Url,m.Iconic,m.Name);
                if (count > 0)
                    GetChildMenus(ref sb, menusChild);//二级菜单
                sb.Append("</li>");
                firstFlag = false;

            }
            ViewBag.Menus = sb.ToString();
            return View();
        }
        //递归调用
        public void GetChildMenus(ref StringBuilder sb, IQueryable<SysModule> menus)//二级以上菜单
        {
            int count = 0;
            sb.Append("<ul class='sub-menu'>");
            foreach (var m in menus)
            {
                IQueryable<SysModule> menusChild = db.SysModule.AsQueryable().Where(a => a.ParentID == m.ID);
                count = menusChild.Count();
               
               
                sb.Append("<li>");
                sb.AppendFormat("<a href='{0}'><i class='{1}'></i><span class='title'>{2}</span>{3}</a>", count > 0 ? "javascript:;" : m.Url, m.Iconic, m.Name, count > 0 ? "<span class='arrow '></span>" : "");
                if (count > 0)
                    GetChildMenus(ref sb, menusChild);
                sb.Append("</li>");
               
            }
            sb.Append("</ul>");
           
        }
    }
}
复制代码

去掉提取的li替换成@Html.Raw(ViewBag.Menus)

6.总结

前端这种东西最考验人的耐心,不信你自己拼接一下

最后效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值