layUI树形菜单后端动态加载数据和遇到的bug

layUI树形菜单后端动态加载数据

  • 前言
  • 基本功能演示
  • 实现步骤
    • 动态加载数据
  • 总结

前言

这篇博客主要讲述了layUI树形菜单的各种形态以及配合MySQL数据库中的数据动态加载节点!

基本功能演示

layUI树形菜单后端动态加载数据和遇到的bug_第1张图片
这上面是一个比较全面的树形菜单,下面是有关它的详述图:
layUI树形菜单后端动态加载数据和遇到的bug_第2张图片

实现步骤

第一步肯定是要导入layUI的包啦!

没有的小伙伴们火速下载熬:
https://www.layui.com/

下载完是这样的:
在这里插入图片描述

啊有一个注意事项:我在观看layUI的示例时,我只在其中看到了两个导入的路径:

 
 

但是,如果你在下载的文件里面只把layui.css和layui.js放入项目当中,如下图:

layUI树形菜单后端动态加载数据和遇到的bug_第3张图片

不仅效果出不来还会报错哦!这里可以看到报的是一个404错误

在这里插入图片描述
点进去会看到这样子一个,我大胆猜测使用layui中的tree组件是需要一个tree.js,但是这个文件在我导进去的两个文件中没有,那么为什么官方示例却又ok呢?
在这里插入图片描述
因为爱情?不不不,这边我找到两种解决方法:

第一,像官方示例中一样导入layui.js,但是导文件的时候将整个layui导进去。

layUI树形菜单后端动态加载数据和遇到的bug_第4张图片

layUI树形菜单后端动态加载数据和遇到的bug_第5张图片
第二,导入layui.all.js这个js文件,看到中间那个all就知道它比layui.js要高大上啦嘿嘿嘿,它会比layui.js更加全一点,我也不知道为啥要这样,我看到效果有就完了!

layUI树形菜单后端动态加载数据和遇到的bug_第6张图片
具体实现代码:

通过 tree.render() 方法指定一个元素,便可快速创建一个 tree 实例,我这边是模拟了一串数据,后面讲讲动态加载树形菜单熬:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>



  
  Layui
  
  
  
  



 

tree组件的基础参数,根据需要自个调熬

layUI树形菜单后端动态加载数据和遇到的bug_第7张图片

动态加载数据

首先我们得知道layui需要的数据格式是什么
layUI树形菜单后端动态加载数据和遇到的bug_第8张图片
还真别说,我在这里出了一个bug——tree结构动态展示出来,标题却都是未命名

主要是因为根据数据源设计节点实体类时,我为了偷懒我复制了之前做easyUI的tree组件,但是easyUI和layui的节点标题在源码中是不一样的!导致找不到标题属性就默认为‘未命名’了,可以看到我能把json弹出来:
layUI树形菜单后端动态加载数据和遇到的bug_第9张图片

但当我点击确认后:

layUI树形菜单后端动态加载数据和遇到的bug_第10张图片
解决方法也有两个:

1、更改源码,我刚开始居然试图弄这个,但是我承认我菜鸡我失败了,不过我找了其他人的,貌似是有成功的!

2、老老实实去节点实体类更改标题的名字,改成title~我就是使用这一种方法。

如下节点实体类:

package com.zengjing.vo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class TreeVo {
	/**
	 * 节点ID
	 */
	private String id;
	/**
	 * 显示节点文本
	 */
	private String title;
	/**
	 * 节点状态,open closed
	 */
	private Map state;
	/**
	 * 节点是否被选中 true false
	 */
	private boolean checked = false;
	/**
	 * 节点属性
	 */
	private Map attributes;

	/**
	 * 节点的子节点
	 */
	private List> children = new ArrayList>();

	/**
	 * 父ID
	 */
	private String parentId;
	/**
	 * 是否有父节点
	 */
	private boolean hasParent = false;
	/**
	 * 是否有子节点
	 */
	private boolean hasChildren = false;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String text) {
		this.title = text;
	}

	public Map getState() {
		return state;
	}

	public void setState(Map state) {
		this.state = state;
	}

	public boolean isChecked() {
		return checked;
	}

	public void setChecked(boolean checked) {
		this.checked = checked;
	}

	public Map getAttributes() {
		return attributes;
	}

	public void setAttributes(Map attributes) {
		this.attributes = attributes;
	}

	public List> getChildren() {
		return children;
	}

	public void setChildren(List> children) {
		this.children = children;
	}

	public boolean isHasParent() {
		return hasParent;
	}

	public void setHasParent(boolean isParent) {
		this.hasParent = isParent;
	}

	public boolean isHasChildren() {
		return hasChildren;
	}

	public void setChildren(boolean isChildren) {
		this.hasChildren = isChildren;
	}

	public String getParentId() {
		return parentId;
	}

	public void setParentId(String parentId) {
		this.parentId = parentId;
	}

	public TreeVo(String id, String text, Map state, boolean checked, Map attributes,
                  List> children, boolean isParent, boolean isChildren, String parentID) {
		super();
		this.id = id;
		this.title = text;
		this.state = state;
		this.checked = checked;
		this.attributes = attributes;
		this.children = children;
		this.hasParent = isParent;
		this.hasChildren = isChildren;
		this.parentId = parentID;
	}

	public TreeVo() {
		super();
	}

}

BuildTree创建节点结构方法类:

package com.zengjing.vo;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BuildTree {

	/**
	 * 默认-1为顶级节点
	 * @param nodes
	 * @param 
	 * @return
	 */
	public static  TreeVo build(List> nodes) {

		if (nodes == null) {
			return null;
		}
		List> topNodes = new ArrayList>();

		for (TreeVo children : nodes) {
			String pid = children.getParentId();
			if (pid == null || "0".equals(pid)) {
				topNodes.add(children);
			//如果是顶级节点,那么结束当前循环,继续下一次循环
				continue;
			}
			for (TreeVo parent : nodes) {
				String id = parent.getId();
				if (id != null && id.equals(pid)) {
					parent.getChildren().add(children);
					children.setHasParent(true);
					parent.setChildren(true);
					continue;
				}
			}

		}

//		考虑到一个问题,数据库表中本身没有顶级节点
		TreeVo root = new TreeVo();
		if (topNodes.size() == 1) {
			root = topNodes.get(0);
		} else {
//		假如数据库没有顶级节点,就通过代码创建
			root.setId("000");
			root.setParentId("-1");
			root.setHasParent(false);
			root.setChildren(true);
			root.setChecked(true);
			root.setChildren(topNodes);
			root.setTitle("顶级节点");
			Map state = new HashMap<>(16);
			state.put("opened", true);
			root.setState(state);
		}

		return root;
	}

	/**
	 * 指定idparam为顶级节点
	 * @param nodes
	 * @param idParam
	 * @param 
	 * @return
	 */
	public static  List> buildList(List> nodes, String idParam) {
		if (nodes == null) {
			return null;
		}
		List> topNodes = new ArrayList>();

		for (TreeVo children : nodes) {

			String pid = children.getParentId();
			if (pid == null || idParam.equals(pid)) {
				topNodes.add(children);

				continue;
			}

			for (TreeVo parent : nodes) {
				String id = parent.getId();
				if (id != null && id.equals(pid)) {
					parent.getChildren().add(children);
					children.setHasParent(true);
					parent.setChildren(true);

					continue;
				}
			}

		}
		return topNodes;
	}

}

节点实体类创建后,就在dao层创建一个将数据库的数据通过BuildTree解析为json格式返回,,

	public List> toNode(Menu menu,PageBean pageBean) throws Exception {
		
		List list = this.list(menu, pageBean);
	
		List> nodes = new ArrayList>();
	
		TreeVo treeVo = null;
		
		for (Menu p : list) {
			treeVo = new TreeVo<>();
			treeVo.setId(p.getMenuid());
			treeVo.setTitle(p.getMenuname());
			treeVo.setParentId(p.getParentid());
			Map attributes = new HashMap();
			attributes.put("self", p);
			treeVo.setAttributes(attributes);
			nodes.add(treeVo);
		}
		
		return BuildTree.buildList(nodes,"-1");
	
	}

再在action中输出为json串到前端:

public String menuTree(HttpServletRequest req,HttpServletResponse resp) {
		try {
			ResponseUtil.writeJson(resp, this.md.toNode(null, null));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

writeJson方法内容:


	public static void writeJson(HttpServletResponse response,Object o)throws Exception{
		response.setContentType("text/html;charset=utf-8");
		ObjectMapper om = new ObjectMapper();
		String jsonstr = om.writeValueAsString(o);
		PrintWriter out=response.getWriter();
		out.println(jsonstr.toString());
		out.flush();
		out.close();
	}

后台获取json数据结束,就到了重点的前端,我是通过一个函数使用了ajax获取后台数据,再进行返回,在tree的数据源后直接调用方法即可,我的jsp界面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>



  
  Layui
  
  
  
          
	   
	
	   

	
	  
	   

  





 

最后效果图:

layUI树形菜单后端动态加载数据和遇到的bug_第11张图片

总结

前端果然是一个考验人耐心的东西,呜呜呜,写前端样式有问题一定记得清缓存!!好几次因为这个卡好久了,还有记得不同前端框架的文档肯定有一点差异,不要盲目c代码,我今天就直接血的教训,有问题欢迎指教哦摆摆!

你可能感兴趣的:(前端框架,java,js,html,jquery)