bootstrap-table-treegrid数据量较大时渲染太久了

bootstrap-table-treegrid数据量较大时渲染太久了

一、最近在项目中遇到了一个问题,需求是这样的:

1、实现一个树形表格
2、表格中还有一列 启用/停用 的控制(此功能我用的是一个bootstrap-switch的开关来显示的)

二、存在的问题是页面渲染的特别慢

在实现的过程中首先表格的实现我用的是bootstrap-table,树形结构的展示用的是treegrid,最后发现有一个问题,就是当数据达到600条的时候,表格渲染的就会特别的慢,要等待很长一段时间才能在页面渲染出来数据。

三、为什么会导致页面渲染的这么慢

于是我就开始查阅各种资料,最后发现treegrid一开始是把所有的数据全部加载出来,然后再去匹配父子关系,最后在形成父子结构的树形表格。总结来说使其渲染慢的原因有以下两个:
1)在初始化的时候treegrid就把所有的子节点数据也给渲染出来了,虽然子节点在一开始并没有显示在页面上,但其实是已经被渲染出来了,只是被隐藏起来了而已。
2)bootstrap-switch开关的渲染,由于一开始所有的数据都被渲染出来,所以每一行的 启用/停用 开关也被响应的渲染了很多次。
反反复复的操作DOM元素,再加上数据量大,所以就导致了页面渲染的特别慢。

四、解决办法

1、首先给表格做一个分页
2、在初始化表格的时候只让他请求第一级的父节点,页面只显示第一级的父节点,等点击旁边的小加号时,再去请求此父节点所对应的子节点,依次类推。
这样就能解决因为数据量大,操作DOM次数太多所带来的问题。

五、实现代码如下

1、在bootstrap-table的column配置项添加一个放置 + 的列,
有子节点的时候放一个 +,没有子节点的时候放一个 *

columns : [
			{
				field: '',
				title: '',
				align: 'left',
				width:'40px',
				formatter: function(value, row, index) {
					if(row.hasChildren == "true"){
						return "+"
					}else{
						return "*";
					}
				}
			  }
			]

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这样的话,树形结构的样式基本已经实现了,接下来就是实现点击 小加号,展开对应的子集
2、点击父级展开子集

function expanderTree(){
     $("#usermanage").off("click").on("click",".expander",function(){
         plusFun.call(this);
     });
 };

function plusFun(){
< s p a n c l a s s = " t o k e n k e y w o r d " > t h i s < / s p a n > < s p a n c l a s s = " t o k e n o p e r a t o r " > = < / s p a n > < s p a n c l a s s = " t o k e n f u n c t i o n " > this = <spanclass="tokenkeyword">this</span><spanclass="tokenoperator">=</span><spanclass="tokenfunction">(this);
var treeId = $this.parent().parent().data(“uniqueid”), //获取被点击某一行的id
classParent = $this.parent().parent().attr(“id”);
if(!classParent){
classParent = “treegrid-” + treeId;
}
var _level = classParent.split("-").length - 1; //计算是第几级节点,最外层的父级是0,第一级子节点是1,以此类推
var expandFlag = $this.text();
if(expandFlag “+”){
$this.text("-"); //父节点展开后,小图标由 + 变成 -
}else{
< s p a n c l a s s = " t o k e n k e y w o r d " > t h i s < / s p a n > < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > . < / s p a n > < s p a n c l a s s = " t o k e n f u n c t i o n " > t e x t < / s p a n > < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ( < / s p a n > < s p a n c l a s s = " t o k e n s t r i n g " > " + " < / s p a n > < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ) < / s p a n > < s p a n c l a s s = " t o k e n p u n c t u a t i o n " > ; < / s p a n > < s p a n c l a s s = " t o k e n f u n c t i o n " > this.text("+"); <spanclass="tokenkeyword">this</span><spanclass="tokenpunctuation">.</span><spanclass="tokenfunction">text</span><spanclass="tokenpunctuation">(</span><spanclass="tokenstring">"+"</span><spanclass="tokenpunctuation">)</span><spanclass="tokenpunctuation">;</span><spanclass="tokenfunction">("[id^=’"+ classParent +"-’]").remove(); //收缩起父节点的时候,把所对应的子节点都移除掉
return false;
}
//根据父节点的id去请求子节点,然后在追加到父节点的后面
Custom.Ajax({
url : “dep/listchild”,
data : {id:treeId},
dataType : “json”
}, function(jqXHR) {
if(jqXHR.code 0){
var data = jqXHR.data;
}
if(data.length > 0){
data.forEach(function(item){
var str = “”;
str += ‘+ classParent +’-’ + item.id +’" data-index=“0” data-uniqueid="’+ item.id +’">’;
str += ‘’;
if(item.hasChildren == “true”){
str += + _level20 +“px’>*;
}

            str += '</td>';
            str += '<td style="text-align: center;">'+ item.deptCode +'</td>';
            str += '<td style="text-align: center;">'+ item.deptName +'</td>';
            str += '<td style="text-align: center;">'+ item.deptPym +'</td>';
            str += '<td style="text-align: center;">'+ item.deptAddr +'</td>';
            str += '<td style="text-align: center;">'+ item.deptUpk +'</td>';
            str += '<td style="text-align: center;">'+ item.remark +'</td>';
            str += '<td style="text-align: center;">'+ item.gmtModified +'</td>';
            if(item.isEnable == 1){
                str += '<td style="text-align: center;"><input name="status" value="1" class="switch-state" data-size="mini" type="checkbox"></td>'

            }else{
                str += '<td style="text-align: center;"><input name="status" value="0" class="switch-state" data-size="mini" type="checkbox"></td>'

            }

            str += '</tr>';
            $this.parent().parent().after(str);
        })
    }

});

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
六、之前treegrid的写法
// 在 bootstrap-table 的 onLoadSuccess 的配置项里添加
treeShowField : 'deptCode',
parentIdField : 'fatherDeptUpk',
onLoadSuccess : function(data) {
	ajaxTreeTable.Init();  //此方法就是点击 + 号展开子集的封装
	$("#usermanage").treegrid({
		initialState: 'collapsed',
		treeColumn : 0,
		expanderExpandedClass: 'glyphicon glyphicon-minus',
		expanderCollapsedClass: 'glyphicon glyphicon-plus',
		onChange : function() {
			$("#usermanage").bootstrapTable('resetWidth');
		},
	});
}

   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

以上只是我自己的一些认知和体会,如有问题欢迎各位大神的指正,谢谢!

                                

你可能感兴趣的:(spring,boot,遇到的问题)