如何在后台封装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 childList;
}

2、业务代码

public class EvaluationService {
    
    private EvaluationDao evaluationDao;
​
    public List getEvaluations() {
        // 查出所有指标
        List all = evaluationDao.findAll();
        
        // 把所有的数据都放到map中
        Map 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 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 {
​
    public String getId();
​
    public String getParentId();
​
    public void setChildList(List childList);
​
    public List getChildList();
}

工具类实现:

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

public class TreeUtils {
​
    //获取顶层节点
    public static extends DataTree> List getTreeList(String topId, List entityList) {
        
        List resultList = new ArrayList<>();
​
        Map 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 {
​
    private String id;
​
    private String label;
​
    private String parentId;
​
    private List childList;
}

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

public class Test {
    private EvaluationDao evaluationDao;
​
    public List getEvaluations() {
​
        // 接收在数据库中查询到的数据
        List data = evaluationDao.findAll();
​
        // 调用工具类,第一个参数是默认传入的顶级id,和查询出来的数据
        return TreeUtils.getTreeList("0", data);
    }
}

 

你可能感兴趣的:(如何在后台封装el-tree所需要的数据格式)