背景:最近用ExtJS4.2做一個系統,需要在前端展示資源菜單,為樹形結構,該樹形結構是從數據庫動態加載的。
ExtJS的樹形結構大致有兩種情況:
1.靜態樹形結構,此處不多說,看API就能簡單明白;
2.動態加載,ExtJS的特性是根據父節點ID來查詢子節點,從而動態更新樹形菜單,這里有一個缺陷,或許是我孤陋寡聞不知道,那就是無法根據數據庫節點信息自動構建成為一棵樹,記得zTree插件就有這個功能。
那么,我希望能夠根據數據庫樹節點信息自動的構建成一棵樹,就需要自己去寫個小算法在后台拼接成ExtJS需要的數據結構。
代碼部分:
1.節點pojo,必要屬性有:節點ID(id)、父節點ID(parentId)、文本信息(text)、孩子(children),其他屬性,比如節點url,順序order等根據自己需要設置。
public class Resource { private Integer id; private String text; private Integer parentId; private Boolean expanded; private List<Resource> children = new ArrayList<Resource>();
}
2.根據查詢出來的節點List集合拼裝成為前端展示需要的結構,這里寫了個靜態方法。
public static final <T> List<T> buildTree(List<T> nodes) { if(null == nodes || nodes.size() == 0) return null; Map<Integer, T> resources = new HashMap<Integer, T>(); List<T> result = new ArrayList<T>(); try { for(int i=0; i<nodes.size(); i++) { T node = nodes.get(i); Method getId = node.getClass().getMethod("getId"); Integer id = (Integer) getId.invoke(node); resources.put(id, node); } for (Map.Entry<Integer, T> e : resources.entrySet()) { T node = e.getValue(); Method getparentId = node.getClass().getMethod("getParentId"); Integer parentId = (Integer) getparentId.invoke(node); if(parentId == 0) { result.add(node); } else { T parent = resources.get(parentId); if( null != parent) { @SuppressWarnings("unchecked") List<T> children = (List<T>) parent.getClass().getMethod("getChildren").invoke(parent); children.add(node); } } } } catch (Exception e) { e.printStackTrace(); } return result; }
3.數據庫記錄。

4.ExtJS前端代碼。
Ext.onReady(function() { var store = Ext.create('Ext.data.TreeStore', { proxy: { type: 'ajax', url: 'your url' }, root: { text: '系統菜單', id: 0, expanded: true } }); var treePanel = Ext.create('Ext.tree.Panel', { title: '樹形菜單', width: 300, height: 350, margin: '50 0 0 500', store: store, rootVisible: false, useArrows: true, renderTo: Ext.getBody() }); });
5.效果圖。

6.完畢。
