zoukankan      html  css  js  c++  java
  • 如何在后台封装el-tree所需要的数据格式

    背景

    最近遇到了一个分层级展示指标的需求,前端使用el-tree树形组件,要求按官方文档的格式提供数据。

    数据格式:

        id: 1,
        label: '一级 1',
        children: 
            id: 4,
            label: '二级 1-1',
            children: 
                id: 9,
                label: '三级 1-1-1',
                children: ...    
    

    封装思路

    1、首先我们需要获取到所有的节点,新建一个集合result来保存所有顶级节点,也就是parentId为空的或指定值。

    2、然后我们需要找出二级节点存入到顶级节点的childList中,找到三级节点存入到二级节点的childList中,依次类推,最后将result返回。

    代码实现:

    1、设计实体类

    @Data
    public class Evaluation {
        private String id;
        private String label;
        private String parentId;
        private List<Evaluation> childList;
    }
    

    2、业务代码

    public class EvaluationService {
        
        private EvaluationDao evaluationDao;
    
        public List<Evaluation> getEvaluations() {
            // 查出所有指标
            List<Evaluation> all = evaluationDao.findAll();
            
            // 把所有的数据都放到map中
            Map<String, Evaluation> treeMap = new HashMap<>();
            for (int i = 0; i < all.size() && !all.isEmpty(); i++) {
                // 元素的id为键,元素本身为值
                treeMap.put(all.get(i).getId(), all.get(i));
            }
            
            // 将所有顶层节点存入result中
            List<Evaluation> result = new ArrayList<>();
            // 遍历map得到顶层节点或者游离节点
            for (int i = 0; i < all.size(); i++) {
                if (!treeMap.containsKey(all.get(i).getParentId())) {
                    result.add(all.get(i));
                }
            }
    
            // 遍历数据,将对象放入父级节点的childList属性中
            for (int i = 0; i < all.size() && !all.isEmpty(); i++) {
                Evaluation Evaluation = treeMap.get(all.get(i).getParentId());
                if (Evaluation != null) {
                    // 有父节点,校验父节点下childList是否存在,然后将子节点放入
                    if (Evaluation.getChildList() == null) {
                        Evaluation.setChildList(new ArrayList<>());
                    }
                    // 添加到父节点的ChildList集合下
                    Evaluation.getChildList().add(all.get(i));
                }
            }
            return result;
        }
    }
    

    如果项目中使用的不多的话,这样就可以了。实现方式可以有很多种,用上边的方式的好处在于免去了多次到数据库查询的操作,而且可以灵活封装多层级数据,二层、三层、五层等等都可以。

    封装工具类

    为了实现代码的复用,我们可以将上方代码封装成工具类。

    DataTree接口:

    写这个接口类主要是为了下面的工具类,定义泛型T的类型

    public interface DataTree<T> {
    
        public String getId();
    
        public String getParentId();
    
        public void setChildList(List<T> childList);
    
        public List<T> getChildList();
    }
    

    工具类实现:

    以下的泛型T就是接收数据的实体类,要继承上面数据接口类

    public class TreeUtils {
    
        //获取顶层节点
        public static <T extends DataTree<T>> List<T> getTreeList(String topId, List<T> entityList) {
            
            List<T> resultList = new ArrayList<>();
    
            Map<Object, T> treeMap = new HashMap<>();
    
            T itemTree;
    
            for (int i = 0; i < entityList.size() && !entityList.isEmpty(); i++) {
                itemTree = entityList.get(i);
                //把所有的数据放到treeMap中,id为key
                treeMap.put(itemTree.getId(), itemTree);
                //把顶层节点放到集合resultList中
                if (topId.equals(itemTree.getParentId()) || itemTree.getParentId() == null) {
                    resultList.add(itemTree);
                }
            }
    
            //循环数据,把数据放到上一级的childen属性中
            for (int i = 0; i < entityList.size() && !entityList.isEmpty(); i++) {
                itemTree = entityList.get(i);
                T data = treeMap.get(itemTree.getParentId());
                // 不等于null,也就意味着有父节点
                if (data != null) {
                    if (data.getChildList() == null) {
                        data.setChildList(new ArrayList<>());
                    }
                    //把子节点 放到父节点childList当中
                    data.getChildList().add(itemTree);
                    //把放好的数据放回map当中
                    treeMap.put(itemTree.getParentId(), data);
                }
            }
            return resultList;
        }
    }
    

    使用方式:

    1、实体类:

    设计实体类,实现之前定义好的DataTree接口

    @Data
    public class Evaluation implements DataTree<Evaluation> {
    
        private String id;
    
        private String label;
    
        private String parentId;
    
        private List<Evaluation> childList;
    }
    

    2、调用TreeUtils,传入数据和顶层节点id,即可获取到所需要的数据结构。

    public class Test {
        private EvaluationDao evaluationDao;
    
        public List<Evaluation> getEvaluations() {
    
            // 接收在数据库中查询到的数据
            List<Evaluation> data = evaluationDao.findAll();
    
            // 调用工具类,第一个参数是默认传入的顶级id,和查询出来的数据
            return TreeUtils.getTreeList("0", data);
        }
    }
    
  • 相关阅读:
    svn命令
    dos 批处理删除svn目录
    Libevent 的多线程操作
    Linux Daemon 类程序
    模板函数 使用的默认void 模板报错
    配置BUG-Linux系统下ssh登陆很慢的解决办法
    Centos apache + mysql + usvn 配置svn 服务器
    Centos 7U盘安装
    mysql 常用基础
    shell 的 md5 命令
  • 原文地址:https://www.cnblogs.com/hanstrovsky/p/11896290.html
Copyright © 2011-2022 走看看