大湿教我写.net通用权限框架(1)之菜单导航篇_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 大湿教我写.net通用权限框架(1)之菜单导航篇

大湿教我写.net通用权限框架(1)之菜单导航篇

 2013/11/20 12:24:59  微软高级php工程师  博客园  我要评论(0)
  • 摘要:一、坑爹的老板“我X!这个项目是要商业应用的,你还想用easyUI,500美刀的授权费用。一个项目才赚多少钱!赶紧给我换了,明天去客户那边要做demo的,今天晚上必须给我赶出来!不懂的去问大雄”黄总对我又是一通大吼。我容易嘛我,以前做CS架构系统的,现在突然让我转BS,前端开发实在太费力了。更要命的是还碰上一个SB坑爹的小老板。公司一共就三个人,老板(抠得要死,不知道怎么讨到老婆的)、大雄(大湿级攻城湿,BS前端开发大牛)、我(屌丝码农)。二、开工搞起好吧,老板都发话了
  • 标签:.net net 菜单

一、坑爹的老板

      “我X!这个项目是要商业应用的,你还想用easyUI,500美刀的授权费用。一个项目才赚多少钱!赶紧给我换了,明天去客户那边要做demo的,今天晚上必须给我赶出来!不懂的去问大雄”黄总对我又是一通大吼。

我容易嘛我,以前做CS架构系统的,现在突然让我转BS,前端开发实在太费力了。更要命的是还碰上一个SB坑爹的小老板。公司一共就三个人,老板(抠得要死,不知道怎么讨到老婆的)、大雄(大湿级攻城湿,BS前端开发大牛)、我(屌丝码农)。

二、开工搞起

    好吧,老板都发话了,自己重做吧,啥都要搞免费的,怕侵犯别人版权,自己下的片全是正版的么?现在的人啊。。。发再多的牢骚也没用,UI还是得自己写,先弄个好看点的主界面吧,里面的功能随便糊弄下数据库都懒得连。。这次要做的demo是一个后台管理系统,菜单导航做成手风琴的会显得比较大方。那就做成手风琴的吧。经过网上一番搜索,我决定把菜单导航做成下面这个样子

问题来了,上面这个界面是很好看,关键是我不会做呀!那我这个菜鸟只好向大雄大师求教了。

我:“大雄,这个导航菜单怎么做?”

大雄:“没时间,我在改BUG。”

我:“老板让我问你的。”

大雄:“我帮你把界面做好,你能帮我把这250个BUG和需求全改掉?明天就要,多谢你了”

我:“唉,我有个女同学让我帮忙介绍个男朋友”

大雄:“刚好我现在有时间,我先帮你弄”

大雄过来看了一眼我同学的照片说:“网址不是都有了么,自己按F12,什么都有的,我忙去了。。。”

我了个去什么人呀,看人家长得抽象点就撂挑子了,那就F12吧,

擦!F12真是个好东西呀,按一下什么html标记、css样式全有了。原来所谓的前端大湿也不过如此嘛!

不断的ctrl+C、和ctrl+v后,自己再写了点js脚本的我的界面出来啦!!!!完全实现了左侧树状导航,点击完导航在右侧以选项卡的形式打开标签。

这里跟大家分享一下主要思路:

1)每个菜单按钮其实就是一个div,子菜单就是上级div里嵌套div。div真的是个好东西,里面什么东西都能放,菜单图标,样式都可以很好的控制。

2)右侧以选项卡方式打开标签其实是给div加了个onclick事件点击以后在右侧有两个动作:1、加一个iframe,里面放页面内容。2、加一个标签跟页面对应,可以控制页面的显示隐藏和关闭。

附打标签选项卡代码

 1 //=================动态菜单tab标签========================
 2 function AddTabMenu(tabid, url, name, img, Isclose, IsReplace) {
 3     SetSystemId(tabid);
 4     if (url == "" || url == "#") {
 5         url = "/ErrorPage/404.aspx";
 6     }
 7     var tabs_container = top.$("#tabs_container");
 8     var ContentPannel = top.$("#ContentPannel");
 9     if (IsReplace == 'true') {
10         top.RemoveDiv(tabid);
11     }
12     if (Isclose != 'false') { //判断是否带关闭tab
13         top.$(".navigation").hide();
14     } else {
15         top.$(".navigation").show();
16     }
17     if (top.document.getElementById("tabs_" + tabid) == null) { //如果当前tabid存在直接显示已经打开的tab
18         Loading(true);
19         tabs_container.find('li').removeClass('selected');
20         ContentPannel.find('iframe').hide();
21         if (Isclose != 'false') { //判断是否带关闭tab
22             tabs_container.append("<li id=\"tabs_" + tabid + "\" class='selected' win_close='true'><span title='" + name + "' onclick=\"javascript:AddTabMenu('" + tabid + "','" + url + "','" + name + "','" + img + "','true')\"><a href=\"javascript:;\"><img src=\"/Themes/Images/32/" + img + "\" width=\"20\" height=\"20\">" + name + "</a></span><a class=\"win_close\" title=\"关闭当前窗口\" onclick=\"RemoveDiv('" + tabid + "')\"></a></li>");
23         } else {
24             tabs_container.append("<li id=\"tabs_" + tabid + "\" class=\"selected\" onclick=\"javascript:AddTabMenu('" + tabid + "','" + url + "','" + name + "','" + img + "','false')\"><a><img src=\"/Themes/Images/32/" + img + "\" width=\"20\" height=\"20\">" + name + "</a></li>");
25         }
26         ContentPannel.append("<iframe id=\"tabs_iframe_" + tabid + "\" name=\"tabs_iframe_" + tabid + "\" height=\"100%\" width=\"100%\" src=\"" + url + "\" frameBorder=\"0\"></iframe>");
27     }
28     else {
29         tabs_container.find('li').removeClass('selected');
30         ContentPannel.find('iframe').hide();
31         tabs_container.find('#tabs_' + tabid).addClass('selected');
32         top.document.getElementById("tabs_iframe_" + tabid).style.display = 'block';
33     }
34 }
35 //关闭当前tab
36 function ThisCloseTab() {
37     var tabs_container = top.$("#tabs_container");
38     top.RemoveDiv(tabs_container.find('.selected').attr('id').substr(5));
39 }
40 //关闭事件
41 function RemoveDiv(obj) {
42     var tabs_container = top.$("#tabs_container");
43     var ContentPannel = top.$("#ContentPannel");
44     tabs_container.find("#tabs_" + obj).remove();
45     ContentPannel.find("#tabs_iframe_" + obj).remove();
46     var tablist = tabs_container.find('li');
47     var pannellist = ContentPannel.find('iframe');
48     if (tablist.length > 0) {
49         tablist[tablist.length - 1].className = 'selected';
50         pannellist[tablist.length - 1].style.display = 'block';
51     }
52     if (tablist.length == '1') {
53         top.$(".navigation").show();
54     }
55 }

三、举一反三

我:“大雄,原来做前端就是这么简单呀,套套js和样式,P两张好看点的图,找几张图片,什么样的界面出不来呀”

大雄:“可不就是这么简单么,只是你太SB而已,到现在才明白”

好吧!你牛,我TM把你以前那两套UI前端界面也仿出来,不就是F12么,我js好歹还是会点的。半小时后。。。

   

四、动态加载

“哦耶耶,你之前弄的那几套风格的界面都让我扒过来了”

大雄:“哟!我穿过的,都让你给扒了,不错嘛,名师出高徒呀”

我:“狗P名湿,你教我啥啦?”

大雄:“F12呀,对了你那个菜单能动态加载吗?”

我:“动态加载?html的怎么动态加载?”

大雄:“你SB呀,你不知道用JS从后台获取菜单数据,然后自动拼接出菜单来,再加载,不就动态了么?会个F12就这么嚣张了”

我:“JS里面可以拼接html,你怎么不早讲,什么东西都藏着掖着的”

大雄:“我这么忙,你不问我,我怎么知道你想要什么,你当我是websocket时不是还给你那个消息推送啊。”

好吧,还是得自己来做,那个清高的大湿只会骂我的时候话多一点。。。

动态加载要做到以下几步:

1、要在数据库里建立菜单,表结构如下:

序号

列名

数据类型

长度

小数位

标识

主键

外键

允许空

默认值

说明

1

MenuId

varchar

50

0

 

 

 

菜单主键

2

ParentId

varchar

50

0

 

 

 

 

父级主键

3

Code

varchar

50

0

 

 

 

 

编号

4

FullName

varchar

50

0

 

 

 

 

名称

5

Description

varchar

200

0

 

 

 

 

描述

6

Img

varchar

50

0

 

 

 

 

图标

7

Category

varchar

50

0

 

 

 

 

菜单分类

8

NavigateUrl

varchar

200

0

 

 

 

 

导航地址

9

FormName

varchar

200

0

 

 

 

 

窗体名

10

Target

varchar

50

0

 

 

 

 

目标

11

IsUnfold

int

4

0

 

 

 

 

是否展开

12

AllowEdit

int

4

0

 

 

 

 

允许编辑

13

AllowDelete

int

4

0

 

 

 

 

允许删除

14

Enabled

int

4

0

 

 

 

1

有效:1-有效,0-无效

15

SortCode

int

4

0

 

 

 

 

排序吗

16

DeleteMark

int

4

0

 

 

 

1

删除标记:1-正常,0-删除

17

CreateDate

datetime

8

3

 

 

 

getdate

创建时间

18

CreateUserId

varchar

50

0

 

 

 

 

创建用户主键

19

CreateUserName

varchar

50

0

 

 

 

 

创建用户

20

ModifyDate

datetime

8

3

 

 

 

 

修改时间

21

ModifyUserId

varchar

50

0

 

 

 

 

修改用户主键

22

ModifyUserName

varchar

50

0

 

 

 

 

修改用户

                     主要字段介绍:

                      ParentID:父级主键,正确的带出多级下拉菜单。

                      Img:图片路径,前台加载时根据路径加载菜单图标,使菜单看起来更加漂亮。

                      SortCode:菜单显示的顺序。

2、通过jquery调用ajax调用数据库,从数据库中把菜单的父节点,图片地址、排序方式等调出来,这种后台代码大家都熟就不做详细描述了。

3、页面载入时动态加载,根据ajax方法返回的json数据动态拼接html代码,就跟我们平时写C#代码一样,就是拼接个动态字符串,代码如下

   function resizeLayout() {
            resizeU();
            $(window).resize(resizeU);
            function resizeU() {
                var accordion_head = $('.accordion > li > a'),
                 accordion_body = $('.accordion li > .sub-menu');
                $(".sub-menu").css('height', $(".navigation").height() - 19 - accordion_head.length * accordion_head.height() - accordion_head.length + 'px');
                accordion_head.first().addClass('active').next().slideDown('normal');
                accordion_head.on('click', function (event) {
                    event.preventDefault();
                    if ($(this).attr('class') != 'active') {
                        accordion_body.slideUp('normal');
                        $(this).next().stop(true, true).slideToggle('normal');
                        accordion_head.removeClass('active');
                        $(this).addClass('active');
                    }
                });
            }
        }
        //手风琴导航菜单
        var AccordionMenuJson = "";
        function GetAccordionMenu() {
            var index = 0;
            var html = "";
            getAjax("Frame.ashx", "action=LoadFirstMenu", function (data) {
                AccordionMenuJson = eval("(" + data + ")");
                $.each(AccordionMenuJson, function (i) {
                    if (AccordionMenuJson[i].ParentId == '9f8ce93a-fc2d-4914-a59c-a6b49494108f') {
                        if (index == 0) {
                            html += "<li><a style=\"border-top: 0px solid #ccc;\"><img src=\"/Themes/Images/32/" + AccordionMenuJson[i].Img + "\">" + AccordionMenuJson[i].FullName + "</a>";
                        } else {
                            html += "<li><a><img src=\"/Themes/Images/32/" + AccordionMenuJson[i].Img + "\">" + AccordionMenuJson[i].FullName + "</a>";
                        }
                        html += GetSubmenu(AccordionMenuJson[i].MenuId);
                        html += "</li>";
                        index++;
                    }
                });
            })
            $(".accordion").append(html);
        }
        //子菜单
        function GetSubmenu(MenuId) {
            var html = "";
            html += "<div class=\"sub-menu\">";
            $.each(AccordionMenuJson, function (i) {
                if (AccordionMenuJson[i].ParentId == MenuId) {
                    html += "<div onclick=\"AddTabMenu('" + AccordionMenuJson[i].MenuId + "', '" + AccordionMenuJson[i].NavigateUrl + "', '" + AccordionMenuJson[i].FullName + "', '" + AccordionMenuJson[i].Img + "', 'true');\" ><img src=\"/Themes/Images/32/" + AccordionMenuJson[i].Img + "\">" + AccordionMenuJson[i].FullName + "</div>";
                }
            });
            html += "</div>";
            return html;
        }

后台的拼接出这些代码以后,就跟我们按F12键以后得到的结果是一样的。

运行一下,咦,怎么界面上啥东西都没有?我擦,忘了在数据库里添加几个测试菜单,当然是空的了。

三分钟后。。。

“大雄,大雄!!!好啦!可以啦。”

怎么没人了?一看时间两点多了。。。还得加几个功能页面进去才可以做demo

唉,苦逼的程序猿伤不起呀。。。。。

谨以此文献给那些像我一样的前端菜鸟,大神们不喜忽喷。。。

附演示地址:

http://223.86.105.239:801  触摸屏版风格

http://223.86.105.239:802  手风琴版风格

http://223.86.105.239:803  桌面版风格

 

 

 

 

发表评论
用户名: 匿名