ASP.NET MVC4 +EF+ EasyUI實現 動態菜單


這段時間沒事,做了一個動態菜單的實現。有很多的地方想的不是很全,做的不夠完善。歡迎大神們拍磚和指點!

話不多說,進入正題:

設計了一個數據庫表:

在設計的時候每一個菜單的子菜單最多能添加 99 個,子菜單編號根據父菜單編號拼接上同級子菜單的個數。

    

這里因為要用到Easyui,一些子段是按照easyui屬性設計的。

EF使用的是數據庫優先方式創建。

貼上代碼:

1.HTML代碼:

 1     <style type="text/css">
 2         header {
 3             height:60px;
 4         }
 5         aside{
 6             float:left;
 7             width:200px;
 8         }
 9         article{
10             margin-left:204px
11         }
12     </style>
13 <body>
14     <header>
15         EasyUI treegrid 實現動態菜單
16     </header>
17 
18     <aside>
19     @*樹形菜單*@
20         <ul id="tt"></ul>
21     </aside>
22     <article>
23         
24     @*treegrid數據表格*@
25 
26     <table id="treegrid" style="width: 600px; height: 400px"></table>
27         
28     @*treegrid的右鍵菜單*@
29     <div id="tree_menu" class="easyui-menu" style="width: 120px;">
30         <div>
31             <span>數據操作</span>
32             <div style="width: 120px;">
33                 <div id="add" data-options="iconCls:'icon-add0'">添加節點</div>
34                 <div id="edit" data-options="iconCls:'icon-edit0'">修改節點</div>
35                 <div id="delete" data-options="iconCls:'icon-delete0'">刪除節點</div>
36             </div>
37         </div>
38         <div id="ref" data-options="iconCls:'icon-new0'">刷 新</div>
39         <div class="menu-sep"></div>
40         <div>Exit</div>
41     </div>
42     @*添加,修改表單(彈窗模式)*@
43     <div class ="treegrid_dialog" style="display: none;">
44         <form id="treegrid_form">
45             @*菜單主鍵*@
46             <input type="hidden" name ="MId"  />
47             @*父菜單編號*@
48             <input type="hidden" name ="pid" id="menuPid" />
49             @*菜單編號*@
50             <input type="hidden" name ="id" />
51             <table>
52                 <tr>
53                     <td>菜單名稱</td><td><input  class="easyui-validatebox" name="text" data-options="required:true" /></td>
54                 </tr>
55                 <tr>
56                     <td>菜單圖標</td><td><input  id="icon" name="iconCls" editable="false"/></td>
57                 </tr>
58                 <tr>
59                     <td>菜單路徑</td><td><input  class="easyui-validatebox" name="url" data-options="required:true" /></td>
60                 </tr>
61                 <tr>
62                     <td>菜單是否選中</td>
63                     <td>
64                         <input id="yes" type="radio" name="checked" value="1" /><label for="yes"></label>
65                         <input id="no" type="radio" name="checked" value="0" /><label for="no"></label>
66                     </td>
67                 </tr>
68             </table>
69         </form>
70     </div>
71     </article>
72 </body>
View Code

2.JavaScript代碼:

  1        var treegrid;
  2         var treegrid_dialog;
  3         var iconData;
  4         $(function () {
  5             //綁定菜單tree數據
  6             $('#tt').tree({
  7                 url: '/System/GetTree'
  8             });
  9 
 10             iconData = [{
 11                 value: '',
 12                 text: '默認'
 13             }, {
 14                 value: 'icon-add',
 15                 text: 'icon-add'
 16             }, {
 17                 value: 'icon-edit',
 18                 text: 'icon-edit'
 19             }, {
 20                 value: 'icon-remove',
 21                 text: 'icon-remove'
 22             }, {
 23                 value: 'icon-save',
 24                 text: 'icon-save'
 25             }, {
 26                 value: 'icon-cut',
 27                 text: 'icon-cut'
 28             }, {
 29                 value: 'icon-ok',
 30                 text: 'icon-ok'
 31             }, {
 32                 value: 'icon-no',
 33                 text: 'icon-no'
 34             }, {
 35                 value: 'icon-cancel',
 36                 text: 'icon-cancel'
 37             }, {
 38                 value: 'icon-reload',
 39                 text: 'icon-reload'
 40             }, {
 41                 value: 'icon-search',
 42                 text: 'icon-search'
 43             }, {
 44                 value: 'icon-print',
 45                 text: 'icon-print'
 46             }, {
 47                 value: 'icon-help',
 48                 text: 'icon-help'
 49             }, {
 50                 value: 'icon-undo',
 51                 text: 'icon-undo'
 52             }, {
 53                 value: 'icon-redo',
 54                 text: 'icon-redo'
 55             }, {
 56                 value: 'icon-back',
 57                 text: 'icon-back'
 58             }, {
 59                 value: 'icon-sum',
 60                 text: 'icon-sum'
 61             }, {
 62                 value: 'icon-tip',
 63                 text: 'icon-tip'
 64             }];
 65 
 66            treegrid= $('#treegrid').treegrid({
 67                         url: '/System/GetTree',
 68                         idField: 'id',
 69                         treeField: 'text',
 70                         columns: [[
 71                             { title: '菜單名稱', field: 'text', width: 180 },
 72                             {
 73                                 title: '菜單圖標', field: 'iconCls', width: 100,
 74                                 formatter: function (value) {
 75                                     if (value!=null) {
 76                                         return '<span class="' + value+ '"></span>';
 77                                     }
 78                                 }
 79                             },
 80                             { title: '菜單路徑', field: 'url', width: 100 },
 81                             { title: '是否選中', field: 'checked', width: 100 }
 82                         ]],
 83                         onContextMenu: function (e, row) {
 84                             e.preventDefault();
 85                             $(this).treegrid('unselectAll');
 86                             $(this).treegrid('select', row.id);
 87                             $('#tree_menu').menu('show', {
 88                                 left: e.pageX,
 89                                 top: e.pageY
 90                             });
 91                         }
 92            });
 93             //刷新treegrid數據
 94             $("#ref").click(function () {
 95                    treegrid.treegrid('reload');
 96                });
 97             //添加節點
 98             $("#add").click(function () {
 99                 //取得選中節點
100                 var node = treegrid.treegrid('getSelected');
101                 //清空表單數據
102                 $("#treegrid_form").form('clear');
103                 $("#no").attr("checked", "true");//添加節點--設置表單(菜單是否選中)--默認選擇‘否’
104                 $("#menuPid").val(node.id); //設置將要添加節點 的 父節點編號
105                 $("#icon").combobox({
106                     //url: '../../Content/data/icondata.json',
107                     //valueField: 'id',
108                     //textField: 'text'
109                     data: iconData
110                 });
111                 treegrid_dialog = $(".treegrid_dialog").show().dialog({
112                     modal: true,
113                     title: '添加 ' + node.text + ' 節點的子節點',
114                     closed: false,
115                     width: 400,
116                     height: 250,
117                     cache: false,
118                     collapsible: true,
119                     maximizable: true,
120                     resizable: true,
121                     buttons: [{
122                         text: '保    存',
123                         plain:true,
124                         iconCls: 'icon-save',
125                         handler: function () {
126                             //數據驗證 通過與否
127                             var validate = $("#treegrid_form").form('validate');
128                             if (validate == false) {
129                                 return false;
130                             }
131 
132                             $.ajax({
133                                 url: '/System/AddMenu',
134                                 data: $("#treegrid_form").serialize(),
135                                 type: 'POST',
136                                 cache: false,
137                                 dataType: 'json',
138                                 success: function (data) {
139                                     if (data && data.Success) {
140                                         $.messager.show({ title: '提示', msg: '' + data.Msg + '', timeout: 5000, showType: 'slide' });
141                                         treegrid_dialog.dialog('close');
142                                         treegrid.treegrid('reload');
143                                     }
144                                     else {
145                                         $.messager.show({ title: '提示', msg: '' + data.Msg + '', timeout: 5000, showType: 'slide' });
146                                         treegrid_dialog.dialog('close');
147                                         treegrid.treegrid('reload');
148                                     }
149                                 }
150                             });
151                         }
152                     }, {
153                         text: '取   消',
154                         iconCls: 'icon-redo',
155                         plain: true,
156                         handler: function () {
157                             treegrid_dialog.dialog('close');
158                         }
159                     }]
160                 });
161             });
162             //編輯節點
163             $("#edit").click(function () {
164                 //取得選中節點
165                 var node = treegrid.treegrid('getSelected');
166                 //清空表單數據
167                 $("#treegrid_form").form('clear');
168                 treegrid_dialog = $(".treegrid_dialog").show().dialog({
169                     modal: true,
170                     title: '編輯 ' + node.text + ' 節點',
171                     closed: false,
172                     width: 400,
173                     height: 250,
174                     cache: false,
175                     collapsible: true,
176                     maximizable: true,
177                     resizable: true,
178                     buttons: [{
179                         text: '保    存',
180                         plain:true,
181                         iconCls: 'icon-save',
182                         handler: function () {
183                             //數據驗證 通過與否
184                             var validate = $("#treegrid_form").form('validate');
185                             if (validate == false) {
186                                 return false;
187                             }
188                             $.ajax({
189                                 url: '/System/EditMenu',
190                                 data: $("#treegrid_form").serialize(),
191                                 type: 'POST',
192                                 cache: false,
193                                 dataType: 'json',
194                                 success: function (data) {
195                                     if (data && data.Success) {
196                                         $.messager.show({ title: '提示', msg: '' + data.Msg + '', timeout: 5000, showType: 'slide' });
197                                         treegrid_dialog.dialog('close');
198                                         treegrid.treegrid('reload');
199                                     }
200                                     else {
201                                         $.messager.show({ title: '提示', msg: '' + data.Msg + '', timeout: 5000, showType: 'slide' });
202                                         treegrid_dialog.dialog('close');
203                                         treegrid.treegrid('reload');
204                                     }
205                                 }
206                             });
207                         }
208                     }, {
209                         text: '取   消',
210                         iconCls: 'icon-redo',
211                         plain: true,
212                         handler: function () {
213                             treegrid_dialog.dialog('close');
214                         }
215                     }]
216                 });
217                 //綁定編輯窗口表單數據
218                 $("#treegrid_form").form('load', node);
219             });
220             //刪除節點
221             $("#delete").click(function () {
222                 //取得選中節點
223                 var node = treegrid.treegrid('getSelected');
224                 $.post('/System/DeleteMenu', { MId: node.MId }, function (data) {
225                     if (data && data.Success) {
226                         $.messager.show({ title: '提示', msg: '' + data.Msg + '', timeout: 5000, showType: 'slide' });
227                         treegrid.treegrid('reload');
228                     }
229                     else {
230                         $.messager.show({ title: '提示', msg: '' + data.Msg + '', timeout: 5000, showType: 'slide' });
231                         treegrid.treegrid('reload');
232                     }
233                 });
234             });
235         });
View Code

3.后台Controller方法

  1        private SYS_UserLimitEntities db = new SYS_UserLimitEntities();
  2 
  3         public ActionResult Index()
  4         {
  5             return View();
  6         }
  7 
  8         #region 取得樹形菜單 + ActionResult GetTree(string id)
  9         /// <summary>
 10         /// 取得樹形菜單
 11         /// </summary>
 12         /// <param name="id">用戶點擊tree時,向后台訪問父菜單編號</param>
 13         /// <returns></returns>
 14         [HttpPost]
 15         public ActionResult GetTree(string id)
 16         {
 17             try
 18             {
 19                 List<Menu> list = null;
 20                 //判斷是否執行點擊tree時,按需加載要擴展的菜單
 21                 if (id != null)
 22                 {
 23                     list = db.Menu.Where(a => a.pid == id).ToList();
 24                 }
 25                 else
 26                 {
 27                     list = db.Menu.Where(a => a.pid == "000").ToList();//取得根菜單
 28                 }
 29                 return Json(list);//返回easyui展示數據的json數據
 30             }
 31             catch (Exception)
 32             {
 33                 throw;
 34             }
 35         } 
 36         #endregion
 37 
 38         #region 添加菜單操作 + ActionResult AddMenu(Menu menu)
 39         /// <summary>
 40         /// 添加菜單操作
 41         /// </summary>
 42         /// <param name="menu">收集到的Menu菜單各個屬性的值</param>
 43         /// <returns></returns>
 44         [HttpPost]
 45         public ActionResult AddMenu(Menu menu)
 46         {
 47             Messages m = new Messages();
 48             try
 49             {
 50                 string newid = null;//將要添加菜單的編號
 51                 //判斷將要添加子菜單的父菜單狀態是否為父菜單狀態/否則修改
 52                 Menu me = db.Menu.Single(a => a.id == menu.pid);
 53                 if (me.state == "open")
 54                 {
 55                     me.state = "closed";
 56                 }
 57                 //取得將要添加子菜單同級菜單-----並倒序排列
 58                 var mlist = db.Menu.Where(a => a.pid == menu.pid).OrderByDescending(a => a.MId).ToList();
 59                 //判斷與將要添加的子菜單的同級菜單數目是否為0
 60                 if (mlist.Count > 0)
 61                 {
 62                     //取得同級菜單編號最大的的最后 兩位 以便計算出將要添加菜單編號
 63                     string id = mlist[0].id;
 64                     int i = Convert.ToInt32(id.Substring(id.Length - 2, 2)) + 1;
 65                     //限定每一個子菜單的數目不得超過99個
 66                     if (i == 100)
 67                     {
 68                         m.Msg = "該菜單的子菜單已經達到最大數目了,你可以選擇創建其他菜單選項";
 69                         return Json(m);
 70                     }
 71                     //判斷子菜單編號后兩位是否為‘01’兩位形式不是則補填為兩位
 72                     newid = i > 9 ? mlist[0].pid + i.ToString() : mlist[0].pid + "0" + i.ToString();
 73                 }
 74                 else
 75                 {
 76                     newid = menu.pid + "01";//沒有同級菜單時候就默認添加菜單的編號為 父菜單編號+‘01’
 77                 }
 78                 //修改將要添加菜單的菜單編號
 79                 menu.id = newid;
 80                 menu.state = "open";
 81                 //寫入數據庫
 82                 db.Menu.Add(menu);
 83 
 84                 db.SaveChanges();
 85                 m.Msg = "成功的添加["+menu.text+"]的菜單節點信息!";
 86                 m.Success = true;
 87                 return Json(m);
 88             }
 89             catch (Exception ex)
 90             {
 91                 m.Msg = "添加失敗!" + ex.Message;
 92                 return Json(m);
 93             }
 94         } 
 95         #endregion
 96 
 97         #region 編輯菜單操作 + ActionResult EditMenu(Menu menu)
 98         /// <summary>
 99         /// 編輯菜單操作
100         /// </summary>
101         /// <param name="menu">收集表單Menu數據</param>
102         /// <returns></returns>
103         [HttpPost]
104         public ActionResult EditMenu(Menu menu)
105         {
106             Messages m = new Messages();
107             try
108             {
109                 //將要修改的菜單添加到EF容器
110                 DbEntityEntry<Menu> entry = db.Entry<Menu>(menu);
111                 //設置包裝類對象狀態為unchanged
112                 entry.State = System.Data.EntityState.Unchanged;
113                 //設置改變的屬性
114                 entry.Property(a => a.text).IsModified = true;
115                 entry.Property(a => a.url).IsModified = true;
116                 entry.Property(a => a.@checked).IsModified = true;
117                 entry.Property(a => a.iconCls).IsModified = true;
118                 //提交數據庫
119                 db.SaveChanges();
120                 m.Msg = "節點["+menu.text+"]的信息修改成功!";
121                 m.Success = true;
122                 return Json(m);
123             }
124             catch (Exception ex)
125             {
126                 m.Msg = "修改失敗!" + ex.Message;
127                 return Json(m);
128             }
129         }
130         #endregion
131 
132         #region 刪除菜單操作 + ActionResult DeleteMenu(int MId)
133         /// <summary>
134         /// 刪除菜單操作
135         /// </summary>
136         /// <param name="MId">將要刪除的菜單編號</param>
137         /// <returns></returns>
138         [HttpPost]
139         public ActionResult DeleteMenu(int MId)
140         {
141             Messages m = new Messages();
142             try
143             {
144                 //取得將要刪除的實體對象
145                 Menu menu = db.Menu.Single(a => a.MId == MId);
146                 // 刪除項有--子菜單時
147                 /*
148                  * 從選中的節點開始,將其節點以及其一下節點都刪除
149                  * --無論從那個節點開始刪除都能自如的將其子菜單以及子子菜單刪除,以此類推
150                 */
151                 List<Menu> mlist = db.Menu.Where(a => a.id.IndexOf(menu.id)>=0).ToList();
152                 if (mlist.Count>0)
153                 {
154                     foreach (var item in mlist)
155                     {
156                         db.Menu.Remove(item);
157                     }
158                 }
159                 db.Menu.Remove(menu);
160                 db.SaveChanges();
161                 m.Msg = "節點已經被成功刪除!";
162                 m.Success = true;
163                 return Json(m);
164             }
165             catch (Exception ex)
166             {
167                 m.Msg = "刪除失敗!" + ex.Message;
168                 return Json(m);
169             }
170         }
171         #endregion
View Code

效果圖如下:

 

 實例下載地址:

http://pan.baidu.com/share/link?shareid=512055&uk=2804979851

功能自己搗鼓,不足之處還望各位看客指出修正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM