您的位置:首页 > 产品设计 > UI/UE

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

2017-01-13 17:16 489 查看
     最近做一个项目,项目中开始使用的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;
  
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息