如何给前端返回树结构数据

项目中经常会有我们需要按照前端提供的接口文档返回数据

其中树型结构很常见,除了ztree、jstree等树,还有一种常用的森林树:

//我们查询出来的list数据中一定要有id和pid来指定对应关系
@ResponseBody
	@RequestMapping("treelist")
	@ApiOperation(notes = "treelist", httpMethod = "GET", value = "树结构的对比分析接口")
	public Object treelist(HttpServletRequest request, HttpServletResponse response) {
		
		try {
			
            //查询出来的数组
			List findAllList = ztAnalysisConfigService.findAllListByZtid(ztid);
			
					List resultList = new ArrayList<>();
					for (ZtAnalysisConfig ztAnalysisConfig : findAllList) {
								ZtAnaTreeNode node = new ZtAnaTreeNode();
								
                                //这里写业务逻辑
								
								resultList.add(node);
							
					}
					List tns = ForestNodeMerger.merge(resultList);
					JSONArray jsonArray = JSONArray.fromObject(tns);
			
			return jsonArray;
		} catch (Exception e) {
			e.printStackTrace();
			HashMap hashMap = new HashMap<>();
			hashMap.put("success", false);
			hashMap.put("message", "请正确配置专题分析配置");
			return hashMap;
		}
		
		
	}



//以下是树结构相关的内部类
/**  
	 * @ClassName: ZtAnaTreeNode  
	 * @Description: TODO(这里用一句话描述这个类的作用)  
	 * @author Administrator  
	 * @date 2020年3月23日  
	 *    
	 */
	public static class ZtAnaTreeNode {

		private String id; // 分析配置的id
		private String pid; // 分析配置项pid
		private String name; //分析配置的名称
		private String tcid; //图层id
		private String tcurl; //图层地址
		private String tcmc; // 图层名称
		private String type; //图层类型
		private String servertype; //服务类型
		private String dictstr; //关联的字典表
		private List> showfield; //显示字段
		private List> outtableheader; //外层表头
		private String classfyfield; //分类字段
		private String countfield; //统计字段
		private String defaultunit; //默认显示单位
		private String shownumber; // 显示位数
		private String relateid; //关联id
		public List children = new ArrayList();
		public String getId() {
			return id;
		}
		public void setId(String id) {
			this.id = id;
		}
		public String getPid() {
			return pid;
		}
		public void setPid(String pid) {
			this.pid = pid;
		}
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getTcid() {
			return tcid;
		}
		public void setTcid(String tcid) {
			this.tcid = tcid;
		}
		public String getTcurl() {
			return tcurl;
		}
		public void setTcurl(String tcurl) {
			this.tcurl = tcurl;
		}
		public String getTcmc() {
			return tcmc;
		}
		public void setTcmc(String tcmc) {
			this.tcmc = tcmc;
		}
		public String getType() {
			return type;
		}
		public void setType(String type) {
			this.type = type;
		}
		public String getServertype() {
			return servertype;
		}
		public void setServertype(String servertype) {
			this.servertype = servertype;
		}
		public String getDictstr() {
			return dictstr;
		}
		public void setDictstr(String dictstr) {
			this.dictstr = dictstr;
		}
		public List> getOuttableheader() {
			return outtableheader;
		}
		public void setOuttableheader(List> outtableheader) {
			this.outtableheader = outtableheader;
		}
		public List> getShowfield() {
			return showfield;
		}
		public void setShowfield(List> showfield) {
			this.showfield = showfield;
		}
		public String getClassfyfield() {
			return classfyfield;
		}
		public void setClassfyfield(String classfyfield) {
			this.classfyfield = classfyfield;
		}
		public String getCountfield() {
			return countfield;
		}
		public void setCountfield(String countfield) {
			this.countfield = countfield;
		}
		public String getDefaultunit() {
			return defaultunit;
		}
		public void setDefaultunit(String defaultunit) {
			this.defaultunit = defaultunit;
		}
		public String getShownumber() {
			return shownumber;
		}
		public void setShownumber(String shownumber) {
			this.shownumber = shownumber;
		}
		public String getRelateid() {
			return relateid;
		}
		public void setRelateid(String relateid) {
			this.relateid = relateid;
		}
		public List getChildren() {
			return children;
		}
		public void setChildren(List children) {
			this.children = children;
		}
		
	}

	public static class ForestNodeManager  {
		
		private List list;// 森林的所有节点
	 
		public ForestNodeManager(ZtAnaTreeNode[] items) {
			list = new ArrayList();
			for (ZtAnaTreeNode treeNode : items) {
				list.add(treeNode);
			}
		}
	 
		public ForestNodeManager(List items) {
			list = items;
		}
	 
		/**
		 * 根据节点ID获取一个节点
		 * 
		 * @param id
		 *            节点ID
		 * @return 对应的节点对象
		 */
		public ZtAnaTreeNode getTreeNodeAT(String id) {
			for (ZtAnaTreeNode treeNode : list) {
				if (id.equals(treeNode.getId()))
					return treeNode;
			}
			return null;
		}
	 
		/**
		 * 获取树的根节点【一个森林对应多颗树】
		 * 
		 * @return 树的根节点集合
		 */
		public List getRoot() {
			List roots = new ArrayList();
			for (ZtAnaTreeNode treeNode : list) {
				if ("0".equals(treeNode.getPid()))
					roots.add(treeNode);
			}
			return roots;
		}
	}

	public static class ForestNodeMerger  {/**
		 * 将节点数组归并为一个森林(多棵树)(填充节点的children域)
		 * 时间复杂度为O(n^2)
		 * @param items 节点域
		 * @return 多棵树的根节点集合
		 */
		public static List merge(ZtAnaTreeNode[] items){
			ForestNodeManager forestNodeManager = new ForestNodeManager(items);
			for (ZtAnaTreeNode treeNode : items) {
				if(!"0".equals(treeNode.getPid())){
					ZtAnaTreeNode t = forestNodeManager.getTreeNodeAT(treeNode.getPid());
					t.getChildren().add(treeNode);
				}
			}
			return forestNodeManager.getRoot();
		}
		
		/**
		 * 将节点数组归并为一个森林(多棵树)(填充节点的children域)
		 * 时间复杂度为O(n^2)
		 * @param items 节点域
		 * @return 多棵树的根节点集合
		 */
		public static List merge(List items){
			ForestNodeManager forestNodeManager = new ForestNodeManager(items);
			for (ZtAnaTreeNode treeNode : items) {
				if(!"0".equals(treeNode.getPid())){
					ZtAnaTreeNode t = forestNodeManager.getTreeNodeAT(treeNode.getPid());
					t.getChildren().add(treeNode);
				}
			}
			return forestNodeManager.getRoot();
		}
	}


返回结果:[{
    id: xxx,
    pid: xxx,
children: [{
    ......
}]
}]

以上的返回结果存在一个问题:没有子节点的数据会有children为[]的情况,我们可以通过后台的递归去消除,也可以在前端递归消除:

function deleteChildren(arr) {
      let childs = arr
      for (let i = childs.length; i--; i > 0) {
        if (childs[i].children) {
          if (childs[i].children.length) {
            this.deleteChildren(childs[i].children)
          } else {
            delete childs[i].children
          }
        }
      }
      return arr
    }

 

你可能感兴趣的:(如何给前端返回树结构数据)