Ztree 是一种树形展示,当你用新型前端框架的时候,你就意味着要学习他的树形展示,但是Ztree它单独自成一体,这样就不用总是学习别的树形展示了,学会Ztree,可以通用;
优点:
1.优异的性能
2.灵活的配置
3.多种功能的组合

适合项目开发
1.树状菜单
2.树状数据的Web显示
3.权限管理等等。

特点:
● zTree v3.0 将核心代码按照功能进行了分割,不需要的代码可以不用加载

● 采用了延迟加载技术,上万节点轻松加载,即使在 IE6 下也能基本做到秒杀

● 兼容 IE、FireFox、Chrome、Opera、Safari 等浏览器

● 支持 JSON 数据

● 支持静态和 Ajax 异步加载节点数据

● 支持任意更换皮肤 / 自定义图标(依靠css)

● 支持极其灵活的 checkbox 或 radio 选择功能

● 提供多种事件响应回调

● 灵活的编辑(增/删/改/查)功能,可随意拖拽节点,还可以多节点拖拽哟

● 在一个页面内可同时生成多个 Tree 实例

● 简单的参数配置实现 灵活多变的功能
一、网站地址
1.Ztree官网:(官网API文档以及Demo演示项方法介绍比较详细)(重点)
http://www.treejs.cn/v3/main.php#_zTreeInfo
2.进阶学习网页原地址:(学习博客)
http://www.cnblogs.com/sylvandu/p/5805592.html
3.入门学习网页原地址:(学习博客)
https://www.toutiao.com/a6519719172337828365/
4. 资源下载地址:(文件夹已有名称为:zTree资料包)(重点)
https://gitee.com/zTree/zTree_v3
5.JQUery下载官网:
https://code.jquery.com/jquery/
6.为知个人笔记(可以把需要记录的笔记写在里面)
https://note.wiz.cn/
7.zTree贴吧 (百度贴吧)
https://tieba.baidu.com/f?kw=ztree

二、关键性代码

  1. zTree加载需要注意的地方
    简单格式:
    必须项 :
    是否为父节点Isparent、节点id、 节点Pid、节点名name
    次需 :
    是否打开(针对于父节点) open、参数 attribute
    扩展项:
    icon 图片等等

基本格式:
必须项 :
是否为父节点Isparent、节点id、 节点Pid、节点名name
Children 子级节点集合。
次需:
是否打开(针对于父节点) open、参数 attribute
扩展项目:……
2.初始化zTree方法
介绍 :万物(恶)之源
简介:这个方法是用来加载指定JSON数据的,nodes则是数据名
.fn.zTree.init(.fn.zTree.init(("#treeDemo"), setting,nodes);

简介:这个方法时拿来加载数据库的无需nodes
.fn.zTree.init(.fn.zTree.init(("#treeDemo"), setting); //arg1:zTree对象页面展示ID,arg2 ztree展示设置。

三、踩到的坑
1.前端F12调试控制台显示:$… is not a function
这个错误弄了半个小时,因为什么呢?因为zTree和EasyUi各有JQuery文件,因为各自都依赖于JQuery,所以里面的JQuery版本不一样,导入的JQuery文件冲突,删除EasyUi里的JQuery就行了。
也有另外一个原因,是因为进行上一步操作后JQuery顺序不正确。
PS:所以直接把JQuery导入放到第一个,这就万无一失了。

2.空的父节点无限重新加载tree
当然我写的这个问题的解决方法,只针对于你做zTree菜单并且使用简单JSON格式方法去展示的时候,当你点开一个空的父节点的时候,它会又把当前的这个tree菜单又加载一遍,然后作为这个空父节点的子节点展示出来,如果遇到这种问题,请你放弃使用简单格式,老老实实用普通JSON格式。

错误图片(来自前端F12调试的控制台):
Ztree树形展示
控制台的Bug:
Ztree树形展示
这个错误挺有意识的,为什么会出现这个错误呢,仔细看你异步加载时候提交方式如何设置的就知道了,当提交方式为get它就来这个错误了,改成post就没有问题了。
四、 子节点无法找到父节点
这个问题也是出现在你使用简单JSON格式来展示你的tree的时候,因为简单格式的ztree 后端返回的JSOn格式并没有定义children这个属性,但是ztree它是可以通过设置支持简单格式的。如图:
Ztree树形展示

当你设置enable为false,它的子节点的就无法查询到父节点了,所以你把enable 设置为 true ,就?了。

Ztree 的Dao层

/**
 * 树形菜单Ztree数据访问层
 * 
 * @author Administrator
 *
 */
public class ZtreeDao extends JSonBaseDao {

	// 第一种 : 简单JSOn格式,通过pid以及id判断
	/**
	 * 拿到菜单栏
	 * 
	 * @param parameter
	 * @return
	 * @throws SQLException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 */
	private List<Map<String, Object>> menuList(Map<String, String[]> parameter) throws SQLException,
			InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
		String sql = "select * from tb_ztree_menu where true";
		String parentid = JSonUtil.getReqParameter(parameter, "parentid");
		if (StringUtils.isNotBlank(parentid)) {
			sql += " and parentid = " + parentid;
		}

		return super.executeQuery(sql, null);
	}

	/**
	 * 将数据库查找出的数据转换为可展示数据
	 * 
	 * @param map
	 * @param ztreeNode
	 */
	private void menuToJson(List<Map<String, Object>> menuList, List<ZtreeNode> ztreeNodeList) {
		ZtreeNode ztreeNode = null;
		if (menuList != null && menuList.size() > 0) {
			for (Map<String, Object> map : menuList) {
				ztreeNode = new ZtreeNode();
				ztreeNode.setId(Integer.valueOf(map.get("menuId").toString()));
				ztreeNode.setpId(Integer.valueOf(map.get("parentId").toString()));
				ztreeNode.setName(map.get("menuName").toString());
				ztreeNode.setIsParent(map.get("isParent").toString());
				ztreeNode.setOpen(map.get("isParent").toString());
				ztreeNode.setAttribute(map);
				ztreeNodeList.add(ztreeNode);
			}
		}
	}

	/**
	 * 子控制器调用该查询方法
	 * 
	 * @param parameter
	 * @return
	 * @throws SQLException
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public List<ZtreeNode> menuJsonList(Map<String, String[]> parameter) throws InstantiationException,
			IllegalAccessException, NoSuchFieldException, SecurityException, SQLException {
		List<Map<String, Object>> menuList = this.menuList(parameter);
		List<ZtreeNode> ztreeNodeList = new ArrayList<>();
		this.menuToJson(menuList, ztreeNodeList);
		return ztreeNodeList;
	}

	// -----------------------------
	// 第二种:标准JSOn格式,标准的 JSON 数据需要嵌套表示节点的父子包含关系

	/**
	 * 将数据库所有的数据加载出来
	 * 
	 * @param parameter
	 * @param pageBean
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 * @throws SQLException
	 */
	public List<Map<String, Object>> menuList(Map<String, String[]> parameter, PageBean pageBean)
			throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException,
			SQLException {
		String sql = "select * from tb_ztree_menu where true";
		String menuId = JSonUtil.getReqParameter(parameter, "menuId");
		if (StringUtils.isNotBlank(menuId)) {
			sql += " and parentId in ( " + menuId + ")";
		} else {
			sql += " and parentId = -1";
		}
		return super.executeQuery(sql, null);
	}

	/**
	 * 步骤: 一.查询所有的信息 二.直接查出来的数据不能展示,然后就需要将所有的数据转换成可展示数据 1.添加所有数据Node
	 * 2.如果当前节点是父节点,则用递归添加子节点 3.写方法啊,还看什么 三.递归方法 四.展示方法
	 * 
	 */

	/**
	 * 将对象转换成可以展示的对象,此方法只针对于当前对象。 使用递归方法将所有对象转换完毕。
	 * 
	 * @param menuList
	 * @param treeNode
	 * @throws SQLException
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public void menuToNode(Map<String, Object> map, ZtreeNode ztreeNode) throws InstantiationException,
			IllegalAccessException, NoSuchFieldException, SecurityException, SQLException {
		// 添加相应的值
		ztreeNode.setId(Integer.valueOf(map.get("menuId").toString()));
		ztreeNode.setpId(Integer.valueOf(map.get("parentId").toString()));
		ztreeNode.setName(map.get("menuName").toString());
		ztreeNode.setIsParent(map.get("isParent").toString());
		ztreeNode.setAttribute(map);
		// 定义数组(用来装载转换后的当前父节点的子节点对象数组)
		List<ZtreeNode> treeNodeList = new ArrayList<>();

		// 定义一个参数数组并且赋予当前节点的Id,用来查询当前父节点的子节点对象
		Map<String, String[]> paramMap = new HashMap<>();
		paramMap.put("menuId", new String[] { ztreeNode.getId() + "" });
		// 开始查询当前父节点的子节点对象、并拿到返回集合
		List<Map<String, Object>> menuChildrenList = this.menuList(paramMap, null);
		// 如果该节点有子节点,那么就得进行子节点的转换操作 通俗点就是如果有儿子就要把儿子丢进去转换一波
		if (menuChildrenList != null && menuChildrenList.size() > 0) {
			ztreeNode.setIsParent("true");//不管数据库是否false与true,只要有子节点,那么设置它是父节点
			ztreeNode.setOpen("true");//设置自动展开
			// 把子节点对象丢过去转换一波
			this.menuListToNodeList(menuChildrenList, treeNodeList);
		}
		// 这里是没有儿子的情况,当父节点没有儿子的时候,我们就把它的自动展开给覆盖,让它不自动展开
		else {
			ztreeNode.setOpen("false");// 是否默认打开跟是否为父节点时一样的,也就是打开所有父节点
		}
		// 将子节点对象添加到treeNode
		ztreeNode.setChildren(treeNodeList);
	}

	/**
	 * 将当前父节点里所有的子节点转换成可以展示的对象,此方法只针对于当前父节点对象的子节点。
	 * 
	 * @param menuList
	 * @param treeNodeList
	 * @throws SQLException
	 * @throws SecurityException
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public void menuListToNodeList(List<Map<String, Object>> menuList, List<ZtreeNode> treeNodeList)
			throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException,
			SQLException {
		ZtreeNode treeNode = null;// 先声明一个对象
		// 将参数menuList父节点的子节点遍历
		for (Map<String, Object> tree : menuList) {
			treeNode = new ZtreeNode();// 这里实例出来
			// 当前对象(也就是当前父节点下所有的子节点),转换为可以展示的对象
			// tree代表当前对象 treeNode代表转换后的对象
			this.menuToNode(tree, treeNode);
			// 然后将转换后的对象添加到集合里面去
			treeNodeList.add(treeNode);
		}
	}

	/**
	 * 展示方法 Action调用该方法
	 * 
	 * @param parameter
	 * @param pageBean
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 * @throws SQLException
	 */
	public List<ZtreeNode> menuTreeList(Map<String, String[]> parameter, PageBean pageBean)
			throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException,
			SQLException {
		// 首先调用查询方法把数据从数据库查出
		List<Map<String, Object>> menuList = this.menuList(parameter, pageBean);
		// 定义菜单数组
		List<ZtreeNode> treeNodeList = new ArrayList<>();
		// 转换一波
		this.menuListToNodeList(menuList, treeNodeList);
		return treeNodeList;// 返回数组,该数组即是所需数组
	}
	// -----------------------------
}

相关文章:

  • 2021-05-31
  • 2021-12-21
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-30
猜你喜欢
  • 2021-06-24
  • 2021-08-13
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案