用easyui DataGrid编辑树形资料

easyui显示编辑树形资料有TreeGrid元件,但是这个元件的vue版本和react版本没有分页功能。virtual scroll功能也表现不佳。

我用DataGrid来处理。要解决的问题点:

(1)如何显示成树形。即,子节点如何有缩进。

先计算好每个节点的层级level,然后template中设置缩进大小。

html 复制代码
<template v-slot:body="{row,column,rowIndex}">
  <div v-Droppable="{dragEnter:onDDKeyDragEnter,drop:onDDKeyDrop}"
    v-Draggable="{row:row,proxy:$refs.DDKeyDragProxy,revert:true,axis:'v',dragStart:onDDKeyDragStart,dragEnd:onDDKeyDragEnd,drag:onDDKeyDrag}"
      @click="onDDKeyClick">
      <span class='tree-indent' :style='{width:(row.acroStates.level*16).toString()+"px"}'></span>
      <span v-if="row.children && row.children.length>0" :class="getDDKeyExpanderClass(row)" @click="onRowToggle($event,row)"></span>
      <span v-else class='tree-indent'></span>
      <span class='tree-title'>{{row[column.field]}}</span>
  </div>
</template>

(2)如何展开和收拢节点。

展开收拢时,计算好每个节点的isVisual属性,通过DataGrid的filter来显示和隐藏。

javascript 复制代码
expandRowRules:[{
  field:'isVisual',
  op:'equal',
  value:true
}],

......
<DataGrid :filterRules="expandRowRules">
......
toggleRow(row){
  if (row.acroStates.state=='open') row.acroStates.state='closed';
  else row.acroStates.state='open';
  let root=row;
  function scanNodes(parent,children){   
    for(let i=0;i<children.length;i++){
      let node=children[i];
      node.isVisual=root.acroStates.state=='open' && parent.acroStates.state=='open';
      if (node.children) scanNodes(node,node.children);
    }
  }
  if (row.children) scanNodes(row,row.children);
},
......
onRowToggle(e,row){
  //console.log('toggle',e,row);
  //this.finishEditing();
  util_treePlain.toggleRow(row);
  this.$refs.tree.doFilter();
  //取消冒泡,使其不触发cellclick事件
  e.cancelBubble=true;
  e.preventDefault();
  e.stopPropagation();
},

(3)排序时如何保持节点的上下级层级关系。

节点按同级排序,按深度优先扫描树形节点,把节点一个个加入到平面的数组中。

javascript 复制代码
expandTree2Plain(treeRows){
  let rows=[];
  function scanNodes(nodes,level){
    for(let i=0;i<nodes.length;i++){
      let node=nodes[i];
      if (!node.acroStates){
        node.acroStates={
          state:'open'
        }
      }
      node.acroStates.level=level;
      node.acroStates.index=rows.length;
      node.isVisual=node.acroStates.state=='open';
      rows.push(node);
      if (node.children){
        scanNodes(node.children,level+1);
      }
    }
  }
  scanNodes(treeRows,0);
  return rows;
},
sortTree2Plain(treeRows,sorts){
  let rows=[];
  function scanNodes(nodes){
    if (sorts && sorts.length>0){
      nodes.sort(function(a,b){
        let r;
        let v1=a[sorts[0].field];          
        let v2=b[sorts[0].field];
        if (v1==null||v1==undefined) v1='';
        if (v2==null||v2==undefined) v2='';
        if (sorts[0].field=='SortNumber'){
          if (v1=='') v1=-1;else v1=parseInt(v1);
          if (v2=='') v2=-1;v2=parseInt(v2);
        }
        if (v1<v2) r=-1;
        else if (v1==v2) r=0;
        else r=1;
        if (sorts[0].order=='desc') r=-r;
        return r;
      });
    }
    for(let i=0;i<nodes.length;i++){
      let node=nodes[i];
      node.acroStates.index=rows.length;
      rows.push(node);
      if (node.children) scanNodes(node.children);
    }
  }
  scanNodes(treeRows);
  //console.log(rows);
  return rows;
},
相关推荐
wordbaby几秒前
PC 屏幕自适应的流行方案解析
前端
Mintopia1 分钟前
Node.js 中path模块的深度解析与实战应用
前端·javascript·node.js
程序员小续2 分钟前
git rebase 和git merge使用及区别
前端·git·后端
静待一世花开2 分钟前
React基础学习
前端
华科云商xiao徐4 分钟前
使用Scrapy编写图像下载程序示例
前端
WillaWang4 分钟前
html结构中图片下方的间隙
前端
阿笑带你学前端5 分钟前
从0到1:我用Flutter造了个全平台IPTV神器,从此看直播不再"精神分裂"!
前端·flutter
ak啊7 分钟前
emit 阶段写入文件系统以及持久化缓存机制
前端·webpack·源码
华科云商xiao徐10 分钟前
利用Python requests库爬虫程序示例
前端
艾克马斯奎普特11 分钟前
一篇文章彻底讲透 CSS 的属性值计算过程,包含选择器优先级、层叠和继承
前端·css