標籤:local 樹節點 提高 標識 取消 展開 手寫 縮排 前台
這幾夜心裡頗不平靜, 奈何 JS水平有限,前台效果耗時四天,後台傳值一天,直至昨夜丑時測試初步完成,其實就是一個給tree來授權,網上開源的外掛程式很多,如treejs、easyui 等等,只是這裡授權稍有不同,如,只能放在Table中去實現。一行一行的寫js,最後寫的差不多有個100多行。
項目原介面不方便,這裡隨手寫個原生態的 Demo
,首先這是一個Table,無論枝節點還是分葉節點都作為一行(tr),功能菜單列表中分葉節點(無分支) 後對應新增、修改等六個功能(複選框)
先來說說前台需要實現的效果:
①點擊枝節點,其下所有的節點(枝/葉)收縮/展開
②點擊枝節點前的複選框,其下所有節點(枝/葉)、分葉節點所在行的新增、修改等複選框勾選/取消
eg: 點擊藍圈中的複選框,則紅框內所有的複選框都被勾選/取消
針對JQ,只要能給每個標籤一個值,name、id之類的用以區別,就能使用Jquery選取器來確定該元素
給所有枝節點嵌套一個 id 為 spid 的標籤<span>用來標識
<tr id="11000"> <td colspan="7"><input name="c0" id="1-0000c" type="checkbox"/><span id="spid" >1-0000</span></td></tr><tr id="11-000" style="text-indent: 10px"> <td><input name="c1" id="11-000c" type="checkbox"/><span>11-000</span></td> <td><input name="A" id="11-000cA" type="checkbox"/></td> <td><input name="B" id="11-000cB" type="checkbox"/></td> <td><input name="C" id="11-000cC" type="checkbox"/></td> <td><input name="D" id="11-000cD" type="checkbox"/></td> <td><input name="E" id="11-000cE" type="checkbox"/></td> <td><input name="F" id="11-000cF" type="checkbox"/></td> </tr>
說白了,就是用Table的方式來實現一個Tree的效果,這裡子節點和分葉節點是用<tr>的縮排長度來達到層級節點的效果
針對收縮/展開
只要能夠選擇到枝節點裡面的span標籤,既可用toggle()來隱藏/展開子節點。根據命名的特點使用拼接id的方法來選擇子節點,即可實現.
然後分情況,依次判斷是滑鼠點擊的是幾級枝節點,如果是一級,則只需要隱藏/展開其下的分葉節點;如果是兩級,要隱藏/展開其下的枝節點、分葉節點;以此類推
比如當點擊籃框所在的枝節點23-000時,分葉節點231-00、23200、枝節點23300及分葉節點2331-0、2332-0 均要隱藏/展開。
var lenth = $(this).parent().parent().attr(‘id‘).indexOf("-"); var s = $(this).parent().parent().attr(‘id‘).substring(0, lenth);
判斷前,先得到當前對象所在的 tr 的 id 中的字元 - 的位置,根據該位置可知當前滑鼠點擊的是何級枝節點,然後隱藏/展開其下節點即可,此時對應的 lenth == 2 ,則有
$(this).parent().parent().siblings("#" + s + i + ‘-‘ + ‘00‘).toggle(); for (var q = 1; q < 6; q++) { if ($("#" + s + i + q + ‘-‘ + ‘0‘).is(":hidden")){ $(this).parent().parent().siblings("#" + s + i + q + ‘-‘ + ‘0‘).toggle(); } $(this).parent().parent().siblings("#" + s + i + q + ‘-‘ + ‘0‘).toggle(); }
若lenth == 3 ,即為最裡層枝節點,則有
$(this).parent().parent().siblings("#" + s + i + ‘-‘ + ‘0‘).toggle();
若lenth ==1 ,即為最外面的枝節點(根節點),同樣是按照id的拼接方法來判斷,不同的是,需要多迴圈一層而已
$(this).parent().parent().siblings("#" + s + i + ‘-‘ + ‘000‘).toggle(); for (var j = 1; j < 6; j++) { if ($("#" + s + i + j + ‘-‘ + ‘00‘).is(":hidden")) { $(this).parent().parent().siblings("#" + s + i + j + ‘-‘ + ‘00‘).toggle(); } $(this).parent().parent().siblings("#" + s + i + j + ‘-‘ + ‘00‘).toggle(); for (var p = 1; p < 6; p++) { if ($("#" + s + i + j + p + ‘-‘ + ‘0‘).is(":hidden")) { $(this).parent().parent().siblings("#" + s + i + j + p + ‘-‘ + ‘0‘).toggle(); } $(this).parent().parent().siblings("#" + s + i + j + p + ‘-‘ + ‘0‘).toggle(); } }
根據觀察比較,發現就是一層一層的去選擇節點,節點越靠外,最外是根節點,那麼需要遍曆的層次就越多,同理,越內側,遍曆次數就越少。用到了大量的 if else 語句,其中又和 for 語句相互嵌套,層層相扣,寫完之後,我的感覺是,除了自己,估計很難有另外一個人能在短時間內明白,自己再也不要去維護自己寫的這個菜單授權。仔細思索,其實是可以進行大量最佳化代碼,比如:點擊第三層需要迴圈第二層和第一層,點擊第二層需要迴圈第一層,點擊第一層需要迴圈其下的分葉節點,那麼我最後的解決方案時採用 直接放在一個方法裡面,然後用$.each() 來遍曆,把分葉節點放在最下面,一層一層,這樣一來,代碼果然看的很舒服,品質也提高不少。
而對於單選/多選/全選/反選
相對來說判斷的情況複雜一些,首先還是分情況討論,思路如下
if 勾選授權行(分葉節點)所在的第一列(11-000、12-000)
其所在行的沒一個首選節點均勾選(新增、修改、刪除等)
else
if 勾選授權行所在的其他列
當個數不少於1一個時,其第一列也要勾選(涉及到背景傳值)
當個數為0時(點擊兩下),其第一列不勾選
else 勾選枝節點時
if 一級節點 遍曆其下
if 二級節點 遍曆其下
if 三級節點 遍曆其下
如此,就把所有的情況都考慮進去,按部就班,一行一行的碼js,即可達到要求,代碼有點多,思路就是這樣,這裡就不貼詳細代碼
上面都是前台的效果,下面來說說後台傳值,這裡有些技巧,值得一說,我給每個授權對應的td 都賦有name 值,這裡其值對應的是角色表中某功能資料中一個列,比如,選擇11-000,新增、刪除;則表中會授權列會記錄 A、B 。寫到這裡,無非就是一些傳值,直接記錄用Ajax傳遞後台接受即可,用Push方法,具體的在 MVC與Ajax應用 中刪除一節有詳細記錄。這裡也不再贅述。寫到這裡,文中唯一值得說兩句的便是下文。當對某個角色的許可權進行修改時,初次載入該介面,Table 表中的複選框 會對照 該角色本身的功能及許可權,會有勾選。說白了就是點擊修改的時候,會有傳值的動作,先去資料庫中 根據該角色的主鍵資訊,撈取其擁有的功能和對應的許可權,根據這些資料Table表中的Checkbox 會有一個初始值。
這裡用到了Each,不得不說真方便。
先在後台拿到 兩列(功能列表、許可權)的集合,然後傳到前台View中(Authlist)
緊接著根據 @Html.Raw(Json.Encode(Authlist)) 將其轉換為Json 數組
再對其遍曆,最後根據其值給授權複選框一個初始值,具體如下:
function getcheck() { $("input[type=checkbox]").prop("checked", false); var data=@Html.Raw(Json.Encode(Authlist)); $.each(data,function(i, item) { var array = item.WebFunctItem.toString().split(‘,‘); var local = item.FunctID.toString().indexOf("0"); var sfunctid = item.FunctID.toString().substring(0, local); $("#" + sfunctid + ‘-‘ + Getzero(local) + ‘u‘).prop("checked", true); for (var i = 0; i < array.length; i++) { $("#" + sfunctid + ‘-‘ +Getzero(local) + ‘u‘+array[i]).prop("checked", true); } }); }
最近都在忙於前台樣式,這個項目進行到此處,著實讓自己的JS水平 提高了一把,業務水平的最好的提高果真就是實踐,然後不斷的測試、測試、測試
市人皆大笑,舉手揶揄之
MVC 樹節點Table格式授權