easyui中最新版本的TreeGrid同步树形表格、同步加异步树形表格、树形表格分页且异步查看子节点

     最近做一个项目,项目中开始使用的TreeTable的一个纯js插件。也许是对这个封装的js不熟悉,不管怎么调试,出来的效果总是不太理想。没得办法,最后想起来easyUI对树形表格的展示效果还不错。

    于是就根据easyUI官方最新的Demo做了下面的案例:


上面依次是TreeGrid同步加异步请求接口且数据未分页、同步加异步请求接口数据分页、同步请求接口未分页。

    为啥要分上面三种呢?因为上面三种方式,请求接口、返回数据,以及携带的参数都不一样。

    一、同步请求接口未分页

    后台接口对应的Model:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * *生成Easyui treeGrid的方法
 */
public class BimPlanComponentTreeGrid implements Serializable{

	private static final long serialVersionUID = 1L;
	
	private String id;
	private String planName;
	private Date planStartTime;
	private Date planEndTime;
	private Integer planTimeLimit;
	private String planTimeLimitUnit;
	private Double planPercentDone;
	private Integer planPriority;
	private String planParentId;
	private Integer planIndex;
	private String planResource;
	private String planRemark;
	private String planFileId;
	private String planState;
	private String state="open";
	private List<BimPlanComponentTreeGrid> children=new ArrayList<BimPlanComponentTreeGrid>();
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPlanName() {
		return planName;
	}
	public void setPlanName(String planName) {
		this.planName = planName;
	}
	public Date getPlanStartTime() {
		return planStartTime;
	}
	public void setPlanStartTime(Date planStartTime) {
		this.planStartTime = planStartTime;
	}
	public Date getPlanEndTime() {
		return planEndTime;
	}
	public void setPlanEndTime(Date planEndTime) {
		this.planEndTime = planEndTime;
	}
	public Integer getPlanTimeLimit() {
		return planTimeLimit;
	}
	public void setPlanTimeLimit(Integer planTimeLimit) {
		this.planTimeLimit = planTimeLimit;
	}
	public String getPlanTimeLimitUnit() {
		return planTimeLimitUnit;
	}
	public void setPlanTimeLimitUnit(String planTimeLimitUnit) {
		this.planTimeLimitUnit = planTimeLimitUnit;
	}
	public Double getPlanPercentDone() {
		return planPercentDone;
	}
	public void setPlanPercentDone(Double planPercentDone) {
		this.planPercentDone = planPercentDone;
	}
	public Integer getPlanPriority() {
		return planPriority;
	}
	public void setPlanPriority(Integer planPriority) {
		this.planPriority = planPriority;
	}
	public String getPlanParentId() {
		return planParentId;
	}
	public void setPlanParentId(String planParentId) {
		this.planParentId = planParentId;
	}
	public Integer getPlanIndex() {
		return planIndex;
	}
	public void setPlanIndex(Integer planIndex) {
		this.planIndex = planIndex;
	}
	public String getPlanResource() {
		return planResource;
	}
	public void setPlanResource(String planResource) {
		this.planResource = planResource;
	}
	public String getPlanRemark() {
		return planRemark;
	}
	public void setPlanRemark(String planRemark) {
		this.planRemark = planRemark;
	}
	public String getPlanFileId() {
		return planFileId;
	}
	public void setPlanFileId(String planFileId) {
		this.planFileId = planFileId;
	}
	public String getPlanState() {
		return planState;
	}
	public void setPlanState(String planState) {
		this.planState = planState;
	}
	public List<BimPlanComponentTreeGrid> getChildren() {
		return children;
	}
	public void setChildren(List<BimPlanComponentTreeGrid> children) {
		this.children = children;
	}
	public String getState() {
		return state;
	}
	public void setState(String state) {
		this.state = state;
	}
}
    特别注意的是:实体类中必须包含state、children这两个属性。其中state="closed"时表示此时的节点是叶级节点,即它是有子级节点;当state="open"时表示此时的节点是子级节点,他没有子级节点。children这个属性是当前实体类集合。所以这里首先就想到需要使用到递归。

    递归数组:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.mss.shtoone.bim.model.BimPlanComponentTreeGrid;

public class BimPlanComponentTreeGridList{
	
	List<BimPlanComponentTreeGrid> returnList = new ArrayList<BimPlanComponentTreeGrid>();
	
	/**
	 * 根据父节点的ID获取所有子节点
	 * @param list 分类表
	 * @param typeId 传入的父节点ID
	 * @return String
	 */
	public List<BimPlanComponentTreeGrid> getChildTreeObjects(List<BimPlanComponentTreeGrid> list,String praentId) {
		List<BimPlanComponentTreeGrid> returnList = new ArrayList<BimPlanComponentTreeGrid>();
		for (Iterator<BimPlanComponentTreeGrid> iterator = list.iterator(); iterator.hasNext();) {
			BimPlanComponentTreeGrid t = (BimPlanComponentTreeGrid) iterator.next();
			// 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
			if (t.getPlanParentId()==praentId) {
				recursionFn(list, t);
				returnList.add(t);
			}
		}
		return returnList;
	}
	
	/**
	 * 递归列表
	 * @param list
	 * @param TreeObject
	 */
	private void  recursionFn(List<BimPlanComponentTreeGrid> list, BimPlanComponentTreeGrid t) {
		List<BimPlanComponentTreeGrid> childList = getChildList(list, t);// 得到子节点列表
		t.setChildren(childList);
		if(childList.size()>0){
			t.setState("closed");
		}else{
			t.setState("open");
		}
		for (BimPlanComponentTreeGrid tChild : childList) {
			if (hasChild(list, tChild)) {// 判断是否有子节点
				//returnList.add(TreeObject);
				Iterator<BimPlanComponentTreeGrid> it = childList.iterator();
				while (it.hasNext()) {
					BimPlanComponentTreeGrid n = (BimPlanComponentTreeGrid) it.next();
					recursionFn(list, n);
				}
			}
		}
	}
	
	// 得到子节点列表
	private List<BimPlanComponentTreeGrid> getChildList(List<BimPlanComponentTreeGrid> list, BimPlanComponentTreeGrid t) {
		List<BimPlanComponentTreeGrid> tlist = new ArrayList<BimPlanComponentTreeGrid>();
		Iterator<BimPlanComponentTreeGrid> it = list.iterator();
		while (it.hasNext()) {
			BimPlanComponentTreeGrid n = (BimPlanComponentTreeGrid) it.next();
			if (n.getPlanParentId()!=null ) {
				if(n.getPlanParentId().equals(t.getId())){
					tlist.add(n);
				}
			}
		}
		return tlist;
	} 
	
     

	// 判断是否有子节点
	private boolean hasChild(List<BimPlanComponentTreeGrid> list, BimPlanComponentTreeGrid t) {
		return getChildList(list, t).size() > 0 ? true : false;
	}
	
	// 本地模拟数据测试
	public static void main(String[] args) {
		long start = System.currentTimeMillis();
		List<BimPlanComponentTreeGrid> TreeObjectList = new ArrayList<BimPlanComponentTreeGrid>();
		
		BimPlanComponentTreeGridList mt = new BimPlanComponentTreeGridList();
		List<BimPlanComponentTreeGrid> ns=mt.getChildTreeObjects(TreeObjectList,null);
		for (BimPlanComponentTreeGrid m : ns) {
			System.out.println(m.getPlanName());
			System.out.println(m.getChildren());
		}
		long end = System.currentTimeMillis();
		System.out.println("用时:" + (end - start) + "ms");
	}
}
后台通过ssh取出来的集合,通过

  new BimPlanComponentTreeGridList().getChildTreeObjects(list,null);  //list为从后台取出来的数据集。(这里是取出所有的数据,无论子父关系,全都交给treeGrid)

前段js展示:

<div class="easyui-layout" fit="true" id="treeGrid" style="height:500px;">
    <table id="treeGridTableDynamic" fit="true" class="easyui-treegrid" ></table>
</div>
---------------------------
$("#treeGridTable").treegrid({
               animate:true,
               idField: 'id',
               treeField:"planName",
               title:"同步[未分页]",
               nowrap: false,
               animate: true,
               method: "GET",
               iconCls: 'icon-save',
               rownumbers: true,
               collapsible: true,
               loadMsg: "数据加载中,请稍后...",
               fitColumns: true,
               fit:true,
               url: url,
               lines: true,   //加树形条
               collapsible:true,//是否可折叠
               showFooter:false,//是否使用页脚
               columns: [[
                   { field:"id", title: "id", hidden: true },
                   { field:"xx", title: "项目名称", width: 200 },
                   { field:"xx", title: "开始时间", align: "center",formatter:dataFormat.formatShort },
                   { field:"xx", title: "终止时间", align: "center",formatter:dataFormat.formatShort }
               ]],
               onBeforeLoad: function(row,param){

               },
               onAfterEdit:function(row,changes){
                   //alert(row.xx);
               },
               onBeforeExpand: function(row){
                   //alert(row.xx);
               }
           });
以上便完成了treeGrid的同步表格的数据展示,结果发现点击第一级请求第二节点时,浏览器崩了,原因是数据量比较多,所以就有了以下的考虑。
同步加载树形结构的第一级,当点击树形表格数据的文件图标时,异步获取他的子级数据。
二、同步加异步请求接口未分页
$("#treeGridTableDynamic").treegrid({
                animate:true,
                idField: 'id',
                treeField:"planName",
                title:"同步加异步[未分页]",
                nowrap: false,
                animate: true,
                method: "GET",
                iconCls: 'icon-save',
                rownumbers: true,
                collapsible: true,
                loadMsg: "数据加载中,请稍后...",
                fitColumns: true,
                fit:true,
                url: url,
                lines: true,   //加树形条
                collapsible:true,//是否可折叠
                showFooter:false,//是否使用页脚
                checkbox: true,
                columns: [[
                    { field:"id", title: "id", hidden: true },
                    { field:"planName", title: "项目名称", width: 200 },
                    { field:"planStartTime", title: "开始时间", align: "center",formatter:dataFormat.formatShort },
                    { field:"planEndTime", title: "终止时间", align: "center",formatter:dataFormat.formatShort }
                ]],
                onBeforeLoad: function(row,param){
                    if (!row) {	// load top level rows
                        param.id = 0;	// set id=0, indicate to load new page rows
                    }else{
                        //这里进行异步请求
                        paramsModel.param1="";
                        paramsModel.param2="";
                        paramsModel.param3="";
                        paramsModel.param4="";
                        paramsModel.param5="";
                        paramsModel.param6="";
                        paramsModel.param7="";
                        paramsModel.param8="";
                        paramsModel.param9=row.id;
                        paramsModel.param10="";
                        paramsModel.page=1;
                        paramsModel.rows=10;
                        var requestNew = JSON.stringify(paramsModel);
                        requestNew = escape(encodeURIComponent(requestNew));  //处理中文乱码之类
                        $(this).treegrid("options").url =APIURL+"rest/getConstructionPlanTreeGridDynamic/"+requestNew+"/"+Key+".json";
                    }
                },
                onAfterEdit:function(row,changes){
                    //alert(row.planName);
                },
                onBeforeExpand: function(row){
                    //alert(row.planName);
                }
            })
此时 onBeforeLoad方法中row,在首次加载树形表格时,我们给他的一个参数=0,所以后台必然有一个当参数=0的时候请求他最高一级节点,即父节点,我们
父节点的parentid=null。而第二次当我们点击树形表格数据的文件图标时,我们后台把父节点的id==parentid作为查询条件返回,即可。
StringBuffer sql=new StringBuffer();
		List<BimPlanComponent> planFileList=new ArrayList<BimPlanComponent>();
		if(StringUtil.isNotEmpty(paramsModel.getParam9())){
			if(paramsModel.getParam9().equalsIgnoreCase("0")){
				sql.append("select a.id,planName,planStartTime,planEndTime,planTimeLimit,planTimeLimitUnit,planPercentDone,planPriority,planParentId,planIndex,planResource,planRemark,planFileId,planState ");
				sql.append("from BIM_ConstructionPlan as a inner join BIM_ConstructionPlanFile as b on a.planFileId=b.id ");
				sql.append(" inner join t_s_depart as c on b.departId=c.id where 1=1 and a.planParentId is NULL ");
				sql.append(sqlWhere.toString());
				List<Object[]> list=findListbySql(sql.toString());
				if(list.size()>0){
					for(int i=0;i<list.size();i++){
						Object[] obj=list.get(i);
						BimPlanComponent plan=new BimPlanComponent();
						plan.setId(String.valueOf(obj[0]));
						plan.setPlanName(StringUtil.isEmptyObject(obj[1], ""));
						plan.setPlanStartTime(GetDate.StrConvertDateShort(StringUtil.isEmptyObject(obj[2],"")));
						plan.setPlanEndTime(GetDate.StrConvertDateShort(StringUtil.isEmptyObject(obj[3],"")));
						plan.setPlanTimeLimit(Integer.parseInt(StringUtil.isEmptyObject(obj[4],null)));
						plan.setPlanTimeLimitUnit(StringUtil.isEmptyObject(obj[5],null));
						plan.setPlanPercentDone(Double.parseDouble(StringUtil.isEmptyObject(obj[6], null)));
						plan.setPlanPriority(Integer.parseInt(StringUtil.isEmptyObject(obj[7],null)));
						plan.setPlanParentId(StringUtil.isEmptyObject(obj[8],null));
						plan.setPlanIndex(Integer.parseInt(StringUtil.isEmptyObject(obj[9],null)));
						plan.setPlanResource(StringUtil.isEmptyObject(obj[10],null));
						plan.setPlanRemark(StringUtil.isEmptyObject(obj[11],null));
						plan.setPlanFileId(StringUtil.isEmptyObject(obj[12],null));
						plan.setPlanState(StringUtil.isEmptyObject(obj[13],null));
						Long longCount=getCountForJdbc("select count(*) from BIM_ConstructionPlan where planParentId='"+plan.getId()+"'");
						if(longCount>0){
							plan.setState("closed");
						}else{
							plan.setState("open");
						}
						planFileList.add(plan);
					}
				}
			}else{
				//清空sql
				sql.setLength(0);
				sql.append("select a.id,planName,planStartTime,planEndTime,planTimeLimit,planTimeLimitUnit,planPercentDone,planPriority,planParentId,planIndex,planResource,planRemark,planFileId,planState ");
				sql.append("from BIM_ConstructionPlan as a inner join BIM_ConstructionPlanFile as b on a.planFileId=b.id ");
				sql.append(" inner join t_s_depart as c on b.departId=c.id where 1=1 and a.planParentId='"+paramsModel.getParam9()+"' ");
				sql.append(sqlWhere.toString());
				List<Object[]> list=findListbySql(sql.toString());
				if(list.size()>0){
					for(int i=0;i<list.size();i++){
						Object[] obj=list.get(i);
						BimPlanComponent plan=new BimPlanComponent();
						plan.setId(String.valueOf(obj[0]));
						plan.setPlanName(StringUtil.isEmptyObject(obj[1], ""));
						plan.setPlanStartTime(GetDate.StrConvertDateShort(StringUtil.isEmptyObject(obj[2],"")));
						plan.setPlanEndTime(GetDate.StrConvertDateShort(StringUtil.isEmptyObject(obj[3],"")));
						plan.setPlanTimeLimit(Integer.parseInt(StringUtil.isEmptyObject(obj[4],null)));
						plan.setPlanTimeLimitUnit(StringUtil.isEmptyObject(obj[5],null));
						plan.setPlanPercentDone(Double.parseDouble(StringUtil.isEmptyObject(obj[6], null)));
						plan.setPlanPriority(Integer.parseInt(StringUtil.isEmptyObject(obj[7],null)));
						plan.setPlanParentId(StringUtil.isEmptyObject(obj[8],null));
						plan.setPlanIndex(Integer.parseInt(StringUtil.isEmptyObject(obj[9],null)));
						plan.setPlanResource(StringUtil.isEmptyObject(obj[10],null));
						plan.setPlanRemark(StringUtil.isEmptyObject(obj[11],null));
						plan.setPlanFileId(StringUtil.isEmptyObject(obj[12],null));
						plan.setPlanState(StringUtil.isEmptyObject(obj[13],null));
						Long longCount=getCountForJdbc("select count(*) from BIM_ConstructionPlan where planParentId='"+plan.getId()+"'");
						if(longCount>0){
							plan.setState("closed");
						}else{
							plan.setState("open");
						}
						planFileList.add(plan);
					}
				}
			}
		}
		return planFileList;
     特别注意每一级节点都要通过数据来判断他的state属性
第一种方式和第二种方式最终返回都是List集合,然后通过GSON格式化成json数据,丢给treeGrid处理。
 虽然第二种方式解决了浏览器被程序卡死的情况。并且每次点击父节点请求子节点时,都只是请求当前父节点的
下一级。但是如果父节点的数据很多的话,我们就要一直拉动滚动条,这样肯定用户使用不方便。
   怎么办呢?于是分页
三、同步加异步请求接口分页
首先通过第二个,我们知道了分页的对象是什么?
       对,是父节点,也就是parent=null的那一级。而父节点下面的所有子节点都不进行分页
所以我们前端,只需要加上分页属性即可
$("#treeGridPageTable").treegrid({
               animate:true,
               idField: 'id',
               treeField:"planName",
               title:"测试TreeGrid[分页]",
               nowrap: true,
               animate: true,
               method: "GET",
               iconCls: 'icon-save',
               collapsible: true,
               loadMsg: "数据加载中,请稍后...",
               rownumbers: true,
               fitColumns: true,
               fit:true,
               url: url,
               lines: true,   //加树形条
               pagination: true,
               pageSize: 5,
               pageList: [5,20,30],
               collapsible:false,//是否可折叠
               showFooter:false,//是否使用页脚
               striped: true,
               collapsible:true,//是否可折叠
               columns: [[
                   { field:"id", title: "id", hidden: true },
                   { field:"planName", title: "项目名称", width: 200 },
                   { field:"planStartTime", title: "开始时间", align: "center",formatter:dataFormat.formatShort },
                   { field:"planEndTime", title: "终止时间", align: "center",formatter:dataFormat.formatShort }
               ]],
               onBeforeLoad: function(row,param){
                   if (!row) {	// load top level rows
                       param.id = 0;	// set id=0, indicate to load new page rows
                   }else{
                       //这里进行异步请求
                       paramsModel.param1="";
                       paramsModel.param2="";
                       paramsModel.param3="";
                       paramsModel.param4="";
                       paramsModel.param5="";
                       paramsModel.param6="";
                       paramsModel.param7="";
                       paramsModel.param8="";
                       paramsModel.param9=row.id;
                       paramsModel.param10="";
                       paramsModel.page=1;
                       paramsModel.rows=10;
                       var requestNew = JSON.stringify(paramsModel);
                       requestNew = escape(encodeURIComponent(requestNew));  //处理中文乱码之类
                       $(this).treegrid("options").url =BIMAPIURL+"rest/getConstructionPlanTreeGridDynamic/"+requestNew+"/"+BIMKey+".json";
                   }
               }
           })

那么后台的json数据自然需要rows和total两个属性
		StringBuffer sql=new StringBuffer();
		List<BimPlanComponent> planFileList=new ArrayList<BimPlanComponent>();
		if(StringUtil.isNotEmpty(paramsModel.getParam9())){
			if(paramsModel.getParam9().equals("0")){
				sql.append("select a.id,planName,planStartTime,planEndTime,planTimeLimit,planTimeLimitUnit,planPercentDone,planPriority,planParentId,planIndex,planResource,planRemark,planFileId,planState ");
				sql.append("from BIM_ConstructionPlan as a inner join BIM_ConstructionPlanFile as b on a.planFileId=b.id ");
				sql.append(" inner join t_s_depart as c on b.departId=c.id where 1=1 and a.planParentId is NULL");
				//这里给其添加条件
				sql.append(sqlWhere.toString());
				List<Map<String, Object>> mapList=findForJdbc(sql.toString(),paramsModel.getPage(),paramsModel.getRows());
				//查询出数据的条数
				//不用分页
				if(mapList.size()>0){
					for(Map<String, Object> map:mapList){
						BimPlanComponent plan=new BimPlanComponent();
						plan.setId(String.valueOf(map.get("id")));
						plan.setPlanName(StringUtil.isEmptyObject(map.get("planName"), null));
						plan.setPlanStartTime(GetDate.StrConvertDateShort(StringUtil.isEmptyObject(map.get("planStartTime"),"")));
						plan.setPlanEndTime(GetDate.StrConvertDateShort(StringUtil.isEmptyObject(map.get("planEndTime"),"")));
						plan.setPlanTimeLimit(Integer.parseInt(StringUtil.isEmptyObject(map.get("planTimeLimit"),null)));
						plan.setPlanTimeLimitUnit(StringUtil.isEmptyObject(map.get("planTimeLimitUnit"),null));
						plan.setPlanPercentDone(Double.parseDouble(StringUtil.isEmptyObject(map.get("planPercentDone"),null)));
						plan.setPlanPriority(Integer.parseInt(StringUtil.isEmptyObject(map.get("planPriority"),null)));
						plan.setPlanParentId(StringUtil.isEmptyObject(map.get("planParentId"),null));
						plan.setPlanIndex(Integer.parseInt(StringUtil.isEmptyObject(map.get("planIndex"),null)));
						plan.setPlanResource(StringUtil.isEmptyObject(map.get("planResource"),null));
						plan.setPlanRemark(StringUtil.isEmptyObject(map.get("planRemark"),null));
						plan.setPlanFileId(StringUtil.isEmptyObject(map.get("planFileId"),null));
						plan.setPlanState(StringUtil.isEmptyObject(map.get("planState"),null));
						//设置state
						Long tempLong=getCountForJdbc("select count(*) from BIM_ConstructionPlan where planParentId='"+plan.getId()+"'");
						if(tempLong>0){
							plan.setState("closed");
						}else{
							plan.setState("open");
						}
						planFileList.add(plan);
					}
				}
			}else{
				sql.setLength(0);  //清空sql
			}
		}
		Map<String, Object> map = new HashMap<String, Object>();
		if(planFileList.size()>0){
			map.put("total", dataCount);
			map.put("rows", planFileList);
		}else{
			map.put("total", 0);
			map.put("rows", "[]");
		}
		return map;





  

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值