编写表格树GridTree过程遇到的问题

项目中用到不少的树和表格,但是要用到表格树的地方不是很多,但是有时候需要的时候却不好找到。所以就在闲暇的时候自己找了一下,结果发现了很简单的,但是不满足项目的需求,于是就看懂了别人的东西之后,再结合自己的理解,干脆就做一个表格树好了。从写下的第一句代码开始,没有想到居然写到了23k大小,而且发现还有很多待完善的地方。编写过程中遇到了一些麻烦问题,后面还好慢慢的解决了,现在对于这些问题还记忆犹新,所以就记录在此,大家有兴趣的看了可以提出意见,感激不尽。

 

需要准备的知识

代码使用了jquery框架,其余就是普通的javascript。具体的用到了javascript的内容有:动态建立表格,dom元素的基本操作,js的面向对象编程,json的数据等。虽然是jquery插件,实际代码中用到的jquery语句尽量的少,因为感觉使用jquery的话肯定是有一些性能的影响,大概jquery的使用的方法只占了10%到15%左右。对于浏览器兼容的问题,现在没有考虑很周到,所以在火狐下面不是很好用,我是用的ie6,不知道ie高版本会不会出现问题。

 

GridTree的基本结构

总体就是一个普通的table,程序是通过读取json数据(实际是js数组)里面的字段,然后通过动态添加表格的方法逐行添加tr,td,在添加行的过程中根据需要设置样式,添加方法等。每一行数据(即tr的dom对象)都有id属性,其值就等于数据中的idColumn对应的列的值,然后加上前缀‘_node’得到。例如加入有一行数据为'id:1,name:renjie120,parentId:-1',那么在形成的tr中要找到这一行的dom对象的话,通过document.getElementByIdx('_node1')就可以找到了。

 

GridTree树形数据层次结构的形成过程

json数据中的每行数据都提供了一个主标示列和父亲列,在配置中我取名叫做‘idColumn’和‘parentColumn’,也不知道合适不。然后表格树的重要一步就是根据这两列形成树形的结构,即把父亲和孩子们进行组织,然后再组装到表格中去。

 

我实现的方法是使用了一个js的hashMap对象(在hashMap.js对象中定义),然后利用hashMap,array就开始了组织树形的过程。主要相关代码如下:

  // 父亲到孩子映射关系(key:父亲id,value:孩子id的集合)
  var parentToChildMap= new HashMap();
  // 孩子到父亲的映射关系(key:孩子id,value:父亲id),方便找到节点的路径而设置这个变量
  var childToFatherMap= new HashMap();
  // 节点id,节点对象映射关系
  var nodeMap= new HashMap();
  // 父亲节点id集合
  var parents= new Array();
  // 第一层的节点集合
  var firstLevelNodes= new Array();
  // 第一层节点的父亲的集合
  var firstLevelParentIds= new Array();
 
GridTree.prototype._makeTable = function(tree,data)
{
 //data就是json数据,实际是一个js数组!
  for (var i = 0; i < data.length; i++) {
   // 取出id列和parent列的内容
    var _id = data[i][tableContent.idColumn];
    var _parent = data[i][tableContent.parentColumn];
    // 如果在父亲数组中找不到这个父亲,就将父亲节点添加到parents中去。防止了出现父亲节点重复的情况
    if (findInArray(parents, '_node'+_parent) == -1)
      parents.push('_node'+_parent);
    // 如果已经在map中存在了该节点的父亲节点,先取出已经存在的内容,再添加新的id
    if (parentToChildMap.containsKey('_node'+_parent)) {
      var arr = parentToChildMap.get('_node'+_parent);
      arr.push('_node'+_id);
      parentToChildMap.put('_node'+_parent, arr);
    } else {
      var arr = new Array();
      arr.push('_node'+_id);
      parentToChildMap.put('_node'+_parent, arr);
    }
    // 添加孩子到父亲的映射关系
    childToFatherMap.put('_node'+_id, '_node'+_parent);
    // 添加节点id到节点的映射关系
    nodeMap.put('_node'+_id, data[i]);
  }
  // 定义一个数组,用来存放第一层节点的父级节点...
  firstLevelParentIds = removeArrayFromOtherArra y(parents, nodeMap.keys());
  // 得到节点中的父亲节点集合
  parents = removeArrayFromOtherArra y(parents, firstLevelParentIds);
  // 下面根据firstLevelParentIds得到要在第一层显示的那些节点的id
  for (var ii = 0; ii < firstLevelParentIds.length; ii++) {
    firstLevelNodes = firstLevelNodes.concat(parentToChildMap
        .get(firstLevelParentIds[ii]));
  }
  ............
}

 

GridTree的动态添加表格

在上面已经形成了相关的分析数据之后,保存在了GridTree的内部对象中,即一些hashMap,array对象中,然后要做的就是根据这里的数组内容进行动态表格的添加。在程序中,有标题行和分页栏,于是使用了tBody,tHead,tFoot的结构进行添加。

关于动态表格添加的具体方法可以在网上随便搜到比较简单。

 

GridTree的分页实现

最先看到的网上的表格树就没有分页的功能。而我这里的表格树是前台分页,即根据全部的json数据进行分页的计算,在点击分页按钮不会到后台再查询。如果要做后台分页的话,肯定要涉及到后台的相关方法,为了简单处理,就没有实现后台分页。

在程序中定义了一个js对象,然后根据传入的json数组进行与分页信息相关的计算,代码如下:

// 分页的相关信息
 var pagingInfo= new Object();

GridTree.prototype._makeTable = function(tree,data)
{。。。。。

 // 总共的第一层节点数目(可以理解为信息总数)
 pagingInfo.allCount = firstLevelNodes.length;
 // 每页的显示信息条数
 pagingInfo.pageSize = tableContent.pageSize;
 // 总共的页数
 pagingInfo.pagesCount = Math.ceil(pagingInfo.allCount / pagingInfo.pageSize
   * 1.0);
 // 当前页数(从1开始计数)
 pagingInfo.currentPage = 1;

。。。

}

 

其他的小小心得

1.在程序中开始考虑要兼容火狐的,但是一个重要的问题是火狐下面不可以使用innerText属性。解决的办法是:

 

function appendText(node, txt) {

   // 如果是ie浏览器

   if (document.all) {

      node.innerText = txt;

  } else {

      var nd = document.createTextNode(txt);

      node.appendChild(nd);

 }

}

 2.关于文本缩进,使用样式 style.textIndent = '5px'就可以缩进5个像素了。在程序中不同级别显示有层次的关系时,用到了这个。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值