首页 > 代码库 > MVC 树节点Table格式授权

MVC 树节点Table格式授权

      这几夜心里颇不平静, 奈何 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=http://www.mamicode.com/@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格式授权