tree控件后台数据结构的生成以及方法的抽取(2)

defaultProps:{ children: 'childList', label: 'categoryName' // 这里的名字要和你封装的数据中的节点的名字一样 } // 点击事件 handleNodeClick: function (data) { console.log("没做处理"); }

方法抽取

上面的方法虽然也能用,但是想把这个方法抽取成一个通用的方法,以后再写的时候就可以直接调取该方法了。抽取的过程中还是遇到了很多的问题的。

例如实体类A是对应数据库中存储节点的表的实体类,但是,实体类中是不存在setChildList、getChildList集合这些方法的。我就把这些存贮信息的字段写在了一个工具类里面,然后方法也在该工具类里。这样返回的时候就要返回一个装有该工具类的一个集合了。还有一个问题就是该工具类中都需要那些字段?因为是一棵树,所以我们需要节点id,几点的父id,节点的名称,以及存储子节点的集合,如果想要更多的数据,可以添加一个 T data泛型,该泛型直接将原本存储节点的实体类对象存储进来。这样所有的数据就都整齐了,数据结构也就完整了。

contrell代码:

因为我们想抽取一个公用的方法,那么参数的类型就是不确定的,即传入的list中元素的类型是不固定的,所以要用到泛型。上面说过了,我们要拿到节点id,父id,以及节点的名称赋值给工具类中对应的字段。但是既然是用泛型,所以就不知道对象类型,所以我们在工具类中是点不出相应的方法来取到值的,我们就要用到反射,反射的知道类中具体的字段或者方法的名字来取值,所以我们在controller来调用工具类的时候就要,将节点id、父id和节点名称传入。当然了还要传入从后台查询到了装有数据的list集合。

contreller代码如下所示:

@RequestMapping("/cateList") @ResponseBody public List<TreeUtils> cateList() throws Exception{ List<TbCategory> tbCategories = categoryService.cateList(); List<TreeUtils> treeList = TreeUtils.getTreeList(tbCategories,"nodeId", "parentId", "categoryName"); return treeList; }

工具类:

// 抽取方法的时候要考虑一个问题,即,返回一个集合,集合中有父节点和字节点,父节点和字节点的类型一定要统一, // 即这里返回的是一个装有TreeUtils类型的集合,那么集合里的父节点和子节点一定都得是TreeUtils类型的 public class TreeUtils<T> { private Integer id; // 节点id private Integer parentId; // 父节点 private String name; // 节点名称 ,返回给前台的是一个装有TreeUtils的集合的数据,所以在前台显示数据的时候,el-tree的lable的名字的和这个一样 private List<TreeUtils> childList; // 父节点中存放子节点的集合 private T data; // 节点数据

方法

/** * @param listData // 从数据库中查询的数据 * @return */ public static List<TreeUtils> getTreeList(List<?> listData ,String id,String parentId,String categoryName) throws Exception{ List<TreeUtils> resultList = new ArrayList<TreeUtils>(); // 最终返回的结果 Map<Integer ,Object> map = new HashMap<Integer,Object>(); for(int i =0;i<listData.size() && !listData.isEmpty();i++){ // 写一个与该方法差不多的方法,将得到TreeUtils的代码抽取出来 // 也可以将listData集合整个转换成装有TreeUtils的集合x,然后再循环x TreeUtils treeUtils = new TreeUtils(); treeUtils.setId(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),id).toString())); // id // 返回值为Object无法直接转换成Integer,先toString,再转换成Integer。这里的返回值写成Object是因为多种类型字段的值都可以用该方法 treeUtils.setParentId(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),parentId).toString())); // 父id treeUtils.setName(TreeUtils.getFileValue(listData.get(i),categoryName).toString()); // 节点名 //System.out.println("节点名为+"+TreeUtils.getFileValue(listData.get(i),categoryName).toString()); treeUtils.setData(listData.get(i)); // data:原对象中的所有属性,无children // 通过反射得到每条数据的id将数据封装的map集合中,id为键,元素本身为值 map.put(treeUtils.getId(),treeUtils); // 将所有顶层元素添加到resultList集合中 //if( 0 == treeUtils.getParentId()){ // resultList.add(treeUtils); // } } // 得到所有的顶层节点,游离节点也算作顶层节点 // 优点一,不用知道等级节点的id // 优点而,只查询了一次数据库 for(int i =0;i<listData.size();i++){ if(!map.containsKey(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),parentId).toString()))){ resultList.add((TreeUtils) map.get(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),id).toString()))); } } for(int i =0;i<listData.size() && !listData.isEmpty();i++){ TreeUtils obj = (TreeUtils)map.get(Integer.parseInt(TreeUtils.getFileValue(listData.get(i), parentId).toString())); if(obj != null){ if(obj.getChildList() == null){ obj.setChildList(new ArrayList()); } obj.getChildList().add(map.get(Integer.parseInt(TreeUtils.getFileValue(listData.get(i),id).toString()))); } } return resultList; }

反射的方法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/5d02ef2ba19008d94b56cdbc4fbbc66e.html