实战:使用jqGrid实现异步树形列表

今天教大家使用jqGrid来实现异步加载的树形列表

先上效果图:

异步加载即不一次性的将所有的数据加载到页面上,只有当需要的时候点击三角按钮,才会将其子类加载到页面上显示,若其下无子类,则是圆圈标识。

下面是实现的步骤:

1.下载并引用必要的文件

这个就不详细讲了,网上有许多教程。

2.前端页面

一个table

一段JS

var jqGrid;
$(function() {
	var width = $(".lz-card-body").width() - 20;
	jqGrid = jQuery('#tree').jqGrid({
        //
		"url" : "/IssueConfig/findByPIdAndLevel",
		"datatype" : "json",
		"colModel" : [ {
			"name" : "issConfigId",
			"index" : "issConfigId",
			"sorttype" : "int",
			"key" : true,
			"hidden" : true
		}, {
			"name" : "descCn",
			"label" : "中文名称",
			"sortable" : false,
			 /* formatter : function(cellvalue, options, rowObject) {
				var viewUrl = "/sysMenu/toView/" + rowObject.id;
				var html = "<a href='" + viewUrl;
				html += "' target=_blank>";
				html += cellvalue;
				html += "</a>";
				return html;
			}  */
		}, {
			"name" : "descEn",
			"label" : "英文名称",
			"sortable" : false
		}, {
			"name" : "issCode",
			"label" : "序号",
			"sortable" : false,
			"align" : "center"
		}, {
			"name" : "issHelp",
			"label" : "问题帮助",
			"sortable" : false,
			"align" : "center"
		}, {
			"name" : "sort",
			"label" : "排序",
			"sortable" : false,
			"align" : "center",
			/* formatter : function(cellvalue, options, rowObject) {
				if(cellvalue){
					return cellvalue.labelCn;
				}
				return '';
			} */
		},  {
			"name" : "operation",
			"label" : "操作",
			"sortable" : false,
			"width" : 100,
			"align" : "center",
			formatter : function(cellvalue, options, rowObject) {
				var id = rowObject.issConfigId;
				var addUrl = "/IssueConfig/toAdd/" + id;
				var editUrl = "/IssueConfig/toEdit/" + id;
				var html = "<a href='" + addUrl;
				html += "' target=_blank title='add'>";
				html += "<i class='fa fa-plus'></i></a>&nbsp;&nbsp;";
				html += "<a href='" + editUrl;
				html += "' target=_blank title='edit'>";
				html += "<i class='far fa-edit'></i></a>";
				html += "&nbsp;&nbsp;<a href='#' title='delete' onclick=deleteMenu(";
				html += id;
				html += ")><i class='fa fa-trash'></i></a>";
				return html;
			}
		}, {
			"name" : "parentId",
			"hidden" : true
		}, {
			"name" : "level",
			"hidden" : true
		}, {
			"name" : "isLeaf",
			"hidden" : true
		}, {
			"name" : "expanded",
			"hidden" : true
		}, {
			"name" : "loaded",
			"hidden" : true
		} ],
		"width" : width,
		"hoverrows" : false,
		"viewrecords" : false,
		"gridview" : true,
		"height" : "auto",
		"sortname" : "issConfigId",
		"sortable" : false,
		"scrollrows" : true,
		"tree_root_level" : 0,
		"treeGrid" : true,
		"ExpandColumn" : "descCn",
		"treedatatype" : "json",
		"treeGridModel" : "adjacency",
		"loadonce" : false,
		"rowNum" : 100,
		"treeReader" : {
			"parent_id_field" : "parentId",
			"level_field" : "level",
			"leaf_field" : "isLeaf",
			"expanded_field" : "expanded",
			"loaded" : "loaded",
			"icon_field" : "icon1"
		}
	});
});

哎.....写的草稿没保存,不想在写一遍了

说一下重要的参数吧

tree_root_level" : 0,
      "treeGrid" : true,
        "ExpandColumn" : "descCn",
        "treedatatype" : "json",
        "treeGridModel" : "adjacency",
        "loadonce" : false,

下面的是详细的api文档,不是太难

https://blog.csdn.net/yjlwl1213/article/details/41750703

3.后台代码

首先要知道,因为是弄清楚前台需要给后台什么参数,后台返给前台的数据结构是什么样子。

1.前台给后台

因为是异步加载,点击父节点才加载出其直接子节点,那么肯定要发回parent id,然后每一层 它的Level都要加1,所以要把父节点的level发回。

/**
	 * 根据parent_id和level查询菜单(异步加载)
	 * 
	 * @param parentId
	 * @param level
	 * @return
	 */
	@RequestMapping(value = "/findByPIdAndLevel", method = RequestMethod.GET)
	@ResponseBody
	public List<IssueConfigVo> findByPIdAndLevel() {
        //获得父节点和父节点的level
		String nodeId = request.getParameter("nodeid");
		String n_level = request.getParameter("n_level");
        //null的话即为最开始加载的level=0的根节点
		Long parentId = StringUtils.isEmpty(nodeId) ? null : Long.parseLong(nodeId);
		Integer level = StringUtils.isEmpty(n_level) ? null : Integer.parseInt(n_level);
		return issueConfigService.getMenusTree(parentId, level);
	}

2.搞清楚要返回的数据结构,怎么样才能被前台识别形成树结构

//返回的类
public class IssueConfigVo extends IssueConfig {
	private static final long serialVersionUID = 1L;

	private Long id;
    //父节点 id 其实这边不需要也可以,因为基础类里面就已经有parent 字段了,只需要在Js中设置一下
	private Long parent;
	private Integer level = 0;
	private boolean isLeaf;
	private boolean loaded = false;
	private boolean expanded = true;
    //数据
	private IssueConfig father;
}
//实体类
@Entity
@Table(name = "NT_T_ISSUE_CONFIG")
public class IssueConfig extends BaseEntity {
	private static final long serialVersionUID = 1L;

	// 主键
	private Long issConfigId;

	// 创建时间
	private Date createDate;

	// 创建人ID
	private String createUserid;

	// 创建人
	private String createUsername;

	// 中文描述
	private String descCn;

	// 英文描述
	private String descEn;

	// 问题序号
	private String issCode;

	// 问题帮助
	private String issHelp;

	// 修改时间
	private Date modifyDate;

	// 修改人员ID
	private String modifyUserid;

	// 上次节点
	private Long parentId;

	// 问题排序
	private Integer sort;

	// 状态
	private String status;
}

3.递归获取List

/**
	 * 递归菜单
	 * 
	 * @param param
	 * @return
	 */
	public List<IssueConfigVo> getMenusTree(Long pid, Integer level) {
		List<IssueConfigVo> issueConfigVoList = new ArrayList<IssueConfigVo>();
        //根据父节点id,找到其直接子节点
		List<IssueConfigVo> issueConfigVo = IssueConfigVo
				.setList(findByParentId(pid));
        //设置level,因为我这边的业务需求,只有两层,如果需要多层,使用level +=1递增
		if (level == null) {
			level = 0;
		} else {
			level = 1;
		}

		if (issueConfigVo != null && !issueConfigVo.isEmpty()) {
			for (IssueConfigVo menuVo : issueConfigVo) {
                //设置子节点属性
				menuVo.setLevel(level);
                //这边是因为刚写的时候不了解,递归获取了子节点,其实是不需要的,
                //因为实体类中有parent字段,我们只需要设置好parentId,并在前端
                //js里面设置好,jqgrid就能将树拼接好
				/*List<IssueConfigVo> children = getMenusTree(menuVo
						.getIssConfigId());*/
				if (children.isEmpty()) {
					menuVo.setIsLeaf(true);
				} else {
					menuVo.setIsLeaf(false);
				}
				// menuVo.setChildren(children);
                //设置parentId,一定要设置
				menuVo.setParent(menuVo.getParentId());
				issueConfigVoList.add(menuVo);
			}
		}
		return issueConfigVoList;
	}
//下面是递归获取子节点,有兴趣的人可以看一下,其实不需要
    /**
	 * 递归菜单
	 * 
	 * @param param
	 * @return
	 */
	public List<IssueConfigVo> getMenusTree(Long pid) {
		List<IssueConfigVo> issueConfigVoList = new ArrayList<IssueConfigVo>();
		List<IssueConfigVo> issueConfigVo = IssueConfigVo
				.setList(findByParentId(pid));

		if (issueConfigVo != null && !issueConfigVo.isEmpty()) {
			for (IssueConfigVo menuVo : issueConfigVo) {
				menuVo.setChildren(getMenusTree(menuVo.getIssConfigId()));
				issueConfigVoList.add(menuVo);
			}
		}
		return issueConfigVoList;
	}

然后树就完成啦!最后,其实js里面也不需要那么麻烦,因为也是第一次写所以不熟悉,下面是精简班,主要功能不变,后台代码也不需要变动

jQuery(grid_selector).jqGrid({
		treeGrid : true,
		width : width,
		treeGridModel : "adjacency",
		ExpandColumn : "descCn",
		ExpandColClick : false,
		url : "/IssueConfig/findByPIdAndLevel",
		datatype : "json",
		colModel : [ {
			name : "issConfigId",
			index : "issConfigId",
			key : true,
			hidden : true, 
			 formatter : function(cellvalue, options, rowObject) {
				var rowId = rowObject.issConfigId;
				var checkbox = '<input type="hidden" name=""';
				checkbox += 'value="';	
				checkbox += rowId
				checkbox += '"/>';
				return checkbox;
			} 
		}, {
			label : nameFormat,
			name : "descCn",
			index : "descCn",
			formatter : function(cellvalue, options, rowObject) {
				index++;
				var rowId = rowObject.issConfigId;
				var descCn = rowObject.descCn;
				var checkbox = '<input type="checkbox" id="chx';
				checkbox += rowId;
				checkbox += '" value="';
				checkbox += descCn;
				checkbox += '" onclick="clickCheckbox(';
				checkbox += rowId;
				checkbox += ', this);"';
				checkbox += 'name=""';
				checkbox += ' />';
				checkbox += rowObject.descCn;
				return checkbox;
			} 
		}, {
			label : "英文名称",
			name : "descEn",
			index : "descEn",
			formatter : function(cellvalue, options, rowObject) {
				var descEn = rowObject.descEn;
				var checkbox = '<input type="hidden" ';
				checkbox += ' name="" value="';
				checkbox += descEn;
				checkbox += '"/>';
				checkbox += rowObject.descEn;
				return checkbox;
			}
		} ,{
			name : "issCode",
			hidden : true,
			formatter : function(cellvalue, options, rowObject) {
				var issCode = rowObject.issCode;
				var checkbox = '<input type="hidden" name=""';
				checkbox += 'value="';	
				checkbox += issCode
				checkbox += '"/>';
				return checkbox;
			}
		}, {
			name : "sort",
			hidden : true,
			formatter : function(cellvalue, options, rowObject) {
				var sort = rowObject.sort;
				var checkbox = '<input type="hidden" name=""';
				checkbox += 'value="';	
				checkbox += sort
				checkbox += '"/>';
				return checkbox;
		} 
		},{
			name : "parentId",
			hidden : true,
			formatter : function(cellvalue, options, rowObject) {
					var parentId = rowObject.parentId;
					var checkbox = '<input type="hidden" name=""';
					checkbox += 'value="';	
					checkbox += parentId
					checkbox += '"/>';
					return checkbox;
			} 
		} ],
		page : false,
		rowNum: 100,
		loadonce : false,
		tree_root_level : 0,
		gridview : true, 
		height : "auto"
	});

有问题可以交流

猜你喜欢

转载自blog.csdn.net/qq_37891064/article/details/83275266
今日推荐