1. 應用需求
在權限系統開發中除了以上數據表關系的設計之外。比較麻煩的地方是級聯模塊在頁面的展示,因為設計中最多是控制到三級,因此三級級聯模塊的展示、編輯等頁面操作是須要解決的問題,這里採用KendoUi中的KendoDropDownList來實現,它能夠輕松的實現我們想要實現的效果。基本效果圖例如以下:
如上圖的關系為:通用支撐子系統(一級)包括:系統管理、用戶管理、日志管理(二級)子系統;系統管理子系統中又包括管理模塊(三級模塊)。
每一級別的變動,其下屬級別模塊均會對應變化。
2. 代碼演示樣例
以下就通過一些代碼解說一下我們前面實現的效果,這里的數據也是模擬我們上面的數據。
頁面的基本效果例如以下:

首先,使用KendoUi須要將對應的js文件引入,這里引入:jquery.min.js以及kendo.all.min.js就可以。
HTML部分:
<link href="kendo.bootstrap.min.css" rel="stylesheet" type="text/css" /> <link href="kendo.common.core.min.css" rel="stylesheet" type="text/css" /> <link href="kendo.common.min.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript" src="kendo.all.min.js"></script> <body> 全部控件的dataSource均來自同一個數組,通過過濾器進行條件過濾 <br/> 父元素:<select id="first"></select> <br /> 子元素:<select id="second"></select> <br /> 子元素詳情:<div id="grid" style="width: 100%; height: 500px;"></div> <br /> </body>
非常easy,就是定義一級模塊、二級模塊的select標簽以及三級模塊的展示標簽div。並給予id屬性。
注意:三級模塊的展示。這里使用的是KendoUi中的KendoGrid,能夠定義我們自己的展示表格,這里暫不介紹KendoGrid的使用,盡管兩者之間有非常多共同的地方。
JS部分:
<script type="text/javascript"> //數據 var globalData = [ {"id":"0","pid":"32","bz_id":"-1","sub_id":"-1","value":"通用支撐子系統"}, {"id":"1","pid":"33","bz_id":"-1","sub_id":"-1","value":"計算資源管理子系統"}, {"id":"1","pid":"34","bz_id":"0","sub_id":"-1","value":"用戶管理"}, {"id":"2","pid":"35","bz_id":"0","sub_id":"-1","value":"日志管理"}, {"id":"3","pid":"36","bz_id":"1","sub_id":"-1","value":"節點負載查看"}, {"id":"4","pid":"37","bz_id":"1","sub_id":"-1","value":"節點使用率查看"}, {"id":"5","pid":"38","bz_id":"0","sub_id":"-1","value":"系統管理"}, {"id":"0","pid":"3211","bz_id":"0","sub_id":"5","value":"管理模塊"}, {"id":"1","pid":"3212","bz_id":"0","sub_id":"1","value":"管理角色"}, {"id":"2","pid":"3213","bz_id":"0","sub_id":"1","value":"管理用戶"}, {"id":"3","pid":"3214","bz_id":"0","sub_id":"2","value":"查看日志"}, {"id":"4","pid":"3215","bz_id":"1","sub_id":"3","value":"網絡負載"}, {"id":"5","pid":"3216","bz_id":"1","sub_id":"3","value":"IO負載"}, {"id":"6","pid":"3217","bz_id":"1","sub_id":"4","value":"CPU使用率"}, {"id":"7","pid":"3218","bz_id":"1","sub_id":"4","value":"內存使用率"} ]; var firstDropDownList = null; var secondDropDownList = null; var grid = null; $(document).ready(function() { //初始化控件 firstDropDownList = $("#first").kendoDropDownList({ dataTextField:"value", dataValueField:"value", dataSource:{ <span style="color:#FF0000;">data:globalData</span> }, <span style="color:#3333FF;">template:kendo.template($("#template").html()),</span> change:function() { //改動值后更新下拉列表2和表格數據 var sed_filter={logic:"and", filters:[]}; var one_filter={field:"bz_id", operator:"eq", value: parseInt(this.dataItem().id)}; var two_filter={field:"sub_id", operator:"eq", value: -1}; sed_filter.filters.push(one_filter); sed_filter.filters.push(two_filter); secondDropDownList.dataSource.filter(sed_filter); var filter={logic:"and", filters:[]}; var bz_filter = {field:"bz_id", operator:"eq", value: parseInt(this.dataItem().id)}; var sub_filter = {field:"sub_id", operator:"eq", value: parseInt(secondDropDownList.dataItem().id)}; filter.filters.push(bz_filter); filter.filters.push(sub_filter); grid.dataSource.filter(filter); } }).data("kendoDropDownList"); secondDropDownList = $("#second").kendoDropDownList({ dataTextField:"value", dataValueField:"value", dataSource:{ <span style="color:#FF0000;">data:globalData</span> }, <span style="color:#3333FF;">template:kendo.template($("#template").html()),</span> change:function() { var filter={logic:"and", filters:[]}; var bz_filter = {field:"bz_id", operator:"eq", value: parseInt(firstDropDownList.dataItem().id)}; var sub_filter = {field:"sub_id", operator:"eq", value: parseInt(this.dataItem().id)}; filter.filters.push(bz_filter); filter.filters.push(sub_filter); grid.dataSource.filter(filter); } }).data("kendoDropDownList"); grid = $("#grid").kendoGrid({ dataSource:{ <span style="color:#FF0000;">data:globalData</span> }, columns:[ { title:"模塊PID", field:"pid" }, { title:"模塊名稱", field:"value" } ] }).data("kendoGrid"); //初始化控件結束 //初始數據過濾 firstDropDownList.dataSource.filter({ field: "bz_id", operator: "eq", value: -1 }); var sed_filter={logic:"and", filters:[]}; var one_filter={field:"bz_id", operator:"eq", value: parseInt(firstDropDownList.dataItem().id)}; var two_filter={field:"sub_id", operator:"eq", value: -1}; sed_filter.filters.push(one_filter); sed_filter.filters.push(two_filter); secondDropDownList.dataSource.filter(sed_filter); var filter={logic:"and", filters:[]}; var bz_filter = {field:"bz_id", operator:"eq", value: parseInt(firstDropDownList.dataItem().id)}; var sub_filter = {field:"sub_id", operator:"eq", value: parseInt(secondDropDownList.dataItem().id)}; filter.filters.push(bz_filter); filter.filters.push(sub_filter); grid.dataSource.filter(filter); }); </script> <span style="color:#3333FF;"><script id="template" type="text/x-kendo-template"> <option id="#:id#" pid="#:pid#" bz_id="#:bz_id#" sub_id="#:sub_id#" value="#:value#">#:value# </option> </script></span>
這里須要注意下面幾點:
1. 控件的數據來源
因為一級模塊、二級模塊以及三級模塊事實上都是屬於模塊一類的數據,因此這三類中的數據能夠採用一套,然后再通過filter控制顯示不同模塊的數據,如上JS代碼中紅色標注的dataSource部分。即採用一份數據:globalData(當然這里的數據能夠是來自於PHP中獲得的數據,假設是採用PHP中的數據的話,則代碼為:data:<?php echo $globalData;?>)。
對於dataSource中data的數據格式必須是JSON的形式。因此不管數據來源是JS或者是PHP其構造成的數據必須是JSON格式。
2. 控件的展示模板
定義控件的展示模板。是為了讓我們更好的控制控件顯示。為控件加入filter,如上JS中的藍色標注部分即為模板的定義以及使用,比如:<option id="#:id#" pid="#:pid#" bz_id="#:bz_id#" sub_id="#:sub_id#" value="#:value#">#:value# </option>,這樣我們就能夠在filter中利用我們定義的空間屬性比如:id、pid、bz_id等對控件相互之間的關系進行控制。
3. 控件的數據過濾filter
filter,即為過濾,它是對控件的dataSource中的data集進行過濾。然后再顯示在控件中。
以下以樣例中的效果為例來解說一下filter的使用。
首先。當初始化時我希望,一級模塊控件中顯示第一個一級模塊。二級模塊中顯示與以及模塊相應的一級模塊包括的二級模塊。而在三級模塊中則顯示與此相應的三級模塊。
初始化時:firstDropDownList.dataSource.filter({ field: "bz_id", operator: "eq", value: -1 });控制一級模塊顯示,這里定義的規則為一級模塊的bz_id == -1;二級模塊則依據一級模塊的值來顯示:
var sed_filter={logic:"and", filters:[]}; var one_filter={field:"bz_id", operator:"eq", value: parseInt(firstDropDownList.dataItem().id)}; var two_filter={field:"sub_id", operator:"eq", value: -1}; sed_filter.filters.push(one_filter); sed_filter.filters.push(two_filter); secondDropDownList.dataSource.filter(sed_filter);這里定義的二級模塊的顯示規則為二級模塊的 bz_id = 一級模塊的值 && sub_id == -1 。
三級模塊則依據一級與二級模塊的值顯示:
var filter={logic:"and", filters:[]}; var bz_filter = {field:"bz_id", operator:"eq", value: parseInt(firstDropDownList.dataItem().id)}; var sub_filter = {field:"sub_id", operator:"eq", value: parseInt(secondDropDownList.dataItem().id)}; filter.filters.push(bz_filter); filter.filters.push(sub_filter); grid.dataSource.filter(filter);
4. 控件的點擊事件
當一級模塊值改變時。二級模塊與三級模塊的值均發生改變;當二級模塊的值改變時三級模塊的值會發生改變。這是通過在KendoDropDownList中的change事件來改變的,至於規則,則非常上面的一樣。以一級模塊改變為例:
change:function() { //改動值后更新下拉列表2和表格數據 <span style="font-family:宋體;"> </span>var sed_filter={logic:"and", filters:[]}; var one_filter={field:"bz_id", operator:"eq", value: parseInt(this.dataItem().id)}; var two_filter={field:"sub_id", operator:"eq", value: -1}; sed_filter.filters.push(one_filter); sed_filter.filters.push(two_filter); secondDropDownList.dataSource.filter(sed_filter); var filter={logic:"and", filters:[]}; var bz_filter = {field:"bz_id", operator:"eq", value: parseInt(this.dataItem().id)}; var sub_filter = {field:"sub_id", operator:"eq", value: parseInt(secondDropDownList.dataItem().id)}; filter.filters.push(bz_filter); filter.filters.push(sub_filter); grid.dataSource.filter(filter); }另外,假設想採用secondDropDownList.dataItem().id來取得模板中的其他屬性值。比如bz_id,sub_id等,則在定義 secondDropDownList的時候必須加上:
var secondDropDownList = $("#xxx").kendoDropDownList({...}).data("kendoDropDownList");的.data部分,否則會報錯。