web 前端常用組件【05】ZTree


   web 項目或多或少都會有涉及到什么人員職稱樹,菜單樹,組織機構樹等。

    歷手三四個項目有大有小,采用的樹前端都是 Ztree。

    有些優秀的J2EE 框架將這些常用的組件都封裝起來,作為模塊化的組件提供給前端,這樣固然是好,開發效率會提升幾倍。

    客戶需求是什么,組件化往上一套,幾分鍾就能搭建起來。

    但這樣程序員真的就是搬磚的了,純純的重復性工作。

1. Ztree 主要的特點

  • ZTree v3.0 將核心代碼按照功能進行了分割,不需要的代碼可以不用加載
  • 采用了 延遲加載 技術,上萬節點輕松加載,即使在 IE6 下也能基本做到秒殺
  • 兼容 IE、FireFox、Chrome、Opera、Safari 等瀏覽器
  • 支持 JSON 數據
  • 支持靜態 和 Ajax 異步加載節點數據
  • 支持任意更換皮膚 / 自定義圖標(依靠css)
  • 支持極其靈活的 checkbox 或 radio 選擇功能
  • 提供多種事件響應回調
  • 靈活的編輯(增/刪/改/查)功能,可隨意拖拽節點,還可以多節點拖拽喲
  • 在一個頁面內可同時生成多個 Tree 實例
  • 簡單的參數配置實現 靈活多變的功能

    詳細的介紹請移步到Ztree官網: http://www.ztree.me/v3/main.php#_zTreeInfo

2. Web 前端

   具體使用框架不同,前端通信請求寫法可能會有差距,但無論使用什么樣的MVC 框架,怎樣封裝/變化,個人認為前端到后端通信方式大致為 Ajax/Websocket。

   首先頁面需要引入JS,ZTree 依賴 JQuery,所以 JQuery 寫到前面位置。

<script type="text/javascript" src='/style/js/jquery.js'></script>
<script type="text/javascript" src='/style/js/jquery.ztree.core-3.5.js'></script>

  其次按照項目需求不同可以進行具體配置。 zTree 配置屬性和初始化方法參照http://www.ztree.me/v3/api.php

var setting = {
        view : {
            showLine : true,
            selectedMulti : false,
            dblClickExpand : false
        },
        data : {
            simpleData : {
                enable : true
            }
        },
        callback : {
            onNodeCreated : this.onNodeCreated,
            onClick : this.onClick
        }
    };

    $.ajax({
        url : 'service/Menu/getMenutree',
        dataType : 'json',
        contenttype : "application/x-www-form-urlencoded;charset=utf-8",
        type : 'POST',
        success : function(data) {
            if (data.success) {
                $.fn.zTree.init($("#treeDemo"), setting, data.returnvalue);
            } else {
                alert("加載菜單樹出錯1!");
            }
        },
        error : function(data) {
            alert("加載菜單樹出錯2");
        }
    });

   最后將后端組織好的 Json 數據初始化入ZTree 即可,具體的 ZTree 使用,比如顯示的樣式,拖拽,點擊事件的響應........都是支持的,看具體需求來實現。

3. Web 后端

    前端的各種樣式事件響應需要一顆細膩的心,如果你們公司前后端是嚴格分工開發的,你完全可以交給前端MM了,專注后端設計。

    下面都為個人理解設計,如看客老爺有更好方式,請斧正。

    首先你得需要一個像 Ztree 樹節點屬性類似的數據結構 POJO(setter,getter 方法已省略)。

    其中只對幾個常用的屬性進行了定義,方便其他人使用,降低業務代碼之間的耦合性。

public class ZTreeNode{
    private static final long serialVersionUID = 8732537724623459243L;
    private Long id;
    private Long pId;
    private String name;
    private Boolean open;
    private Boolean checked;
    private Boolean nocheck;
    private boolean cancheck;
    
    @Override
    public int compareTo(TreeStuffBean o) {
        // TODO Auto-generated method stub
        return 0;
    }
}

     其次你需要一張具有上下級關系的數據表,下面這是自己的測試腳本。

     SQL 無國界,盡管拿去練手吧。

--菜單目錄結構表
create table tb_menu(
 id number(10) not null, --主鍵id
 title varchar2(50), --標題
 parent number(10) --parent id
);
commit;
--父菜單
insert into tb_menu(id, title, parent) values(1, '父菜單1',-1);
insert into tb_menu(id, title, parent) values(2, '父菜單2',-1);
insert into tb_menu(id, title, parent) values(3, '父菜單3',-1);
insert into tb_menu(id, title, parent) values(4, '父菜單4',-1);
insert into tb_menu(id, title, parent) values(5, '父菜單5',-1);
--一級菜單
insert into tb_menu(id, title, parent) values(6, '一級菜單6',1);
insert into tb_menu(id, title, parent) values(7, '一級菜單7',1);
insert into tb_menu(id, title, parent) values(8, '一級菜單8',1);
insert into tb_menu(id, title, parent) values(9, '一級菜單9',2);
insert into tb_menu(id, title, parent) values(10, '一級菜單10',2);
insert into tb_menu(id, title, parent) values(11, '一級菜單11',2);
insert into tb_menu(id, title, parent) values(12, '一級菜單12',3);
insert into tb_menu(id, title, parent) values(13, '一級菜單13',3);
insert into tb_menu(id, title, parent) values(14, '一級菜單14',3);
insert into tb_menu(id, title, parent) values(15, '一級菜單15',4);
insert into tb_menu(id, title, parent) values(16, '一級菜單16',4);
insert into tb_menu(id, title, parent) values(17, '一級菜單17',4);
insert into tb_menu(id, title, parent) values(18, '一級菜單18',5);
insert into tb_menu(id, title, parent) values(19, '一級菜單19',5);
insert into tb_menu(id, title, parent) values(20, '一級菜單20',5);
--二級菜單
insert into tb_menu(id, title, parent) values(21, '二級菜單21',6);
insert into tb_menu(id, title, parent) values(22, '二級菜單22',6);
insert into tb_menu(id, title, parent) values(23, '二級菜單23',7);
insert into tb_menu(id, title, parent) values(24, '二級菜單24',7);
insert into tb_menu(id, title, parent) values(25, '二級菜單25',8);
insert into tb_menu(id, title, parent) values(26, '二級菜單26',9);
insert into tb_menu(id, title, parent) values(27, '二級菜單27',10);
insert into tb_menu(id, title, parent) values(28, '二級菜單28',11);
insert into tb_menu(id, title, parent) values(29, '二級菜單29',12);
insert into tb_menu(id, title, parent) values(30, '二級菜單30',13);
insert into tb_menu(id, title, parent) values(31, '二級菜單31',14);
insert into tb_menu(id, title, parent) values(32, '二級菜單32',15);
insert into tb_menu(id, title, parent) values(33, '二級菜單33',16);
insert into tb_menu(id, title, parent) values(34, '二級菜單34',17);
insert into tb_menu(id, title, parent) values(35, '二級菜單35',18);
insert into tb_menu(id, title, parent) values(36, '二級菜單36',19);
insert into tb_menu(id, title, parent) values(37, '二級菜單37',20);
--三級菜單
insert into tb_menu(id, title, parent) values(38, '三級菜單38',21);
insert into tb_menu(id, title, parent) values(39, '三級菜單39',22);
insert into tb_menu(id, title, parent) values(40, '三級菜單40',23);
insert into tb_menu(id, title, parent) values(41, '三級菜單41',24);
insert into tb_menu(id, title, parent) values(42, '三級菜單42',25);
insert into tb_menu(id, title, parent) values(43, '三級菜單43',26);
insert into tb_menu(id, title, parent) values(44, '三級菜單44',27);
insert into tb_menu(id, title, parent) values(45, '三級菜單45',28);
insert into tb_menu(id, title, parent) values(46, '三級菜單46',28);
insert into tb_menu(id, title, parent) values(47, '三級菜單47',29);
insert into tb_menu(id, title, parent) values(48, '三級菜單48',30);
insert into tb_menu(id, title, parent) values(49, '三級菜單49',31);
insert into tb_menu(id, title, parent) values(50, '三級菜單50',31);
commit;

    當然對於業務 POJO 的數據結構封裝比不可少,主流的持久層框架都能將表映射為 POJO 對象,有自動生成業務接口,服務層。

    不用那些看起來難懂的書面話, 個人理解 POJO 的作用,將現實業務抽象到程序表現層。

public class TbMenu {
    private Long id;
    private String title;
    private Long parent; 
}

    最后是核心的業務處理邏輯,通過持久層獲取想要遍歷的數據,進行處理封裝。

    Map<String, Object> returnvalue = new HashMap<>();
    List<TbMenu> menuList = dataDao.find(TbMenu.class);
    List<ZTreeNode> ZTreeNodeList = new ArrayList<>();
    ZTreeNode treeNode;
    for (TbMenu tbMenu : menuList) {
        treeNode = new ZTreeNode();
        treeNode.setId(tbMenu.getId());
        treeNode.setpId(tbMenu.getParent());
        treeNode.setName(tbMenu.getTitle());
        ZTreeNodeList.add(treeNode);
    }
    treeNode = new ZTreeNode();
    treeNode.setId(-1L);
    treeNode.setpId(0L);
    treeNode.setName("菜單樹");
    treeNode.setOpen(true);
    ZTreeNodeList.add(0, treeNode);

    TreeComparator treeComparator = new TreeComparator();
    Collections.sort(ZTreeNodeList, treeComparator);

   需要注意的地方是最后在 ZTreeNodeList 頭部添加的 treeNode 為樹組件的頭部,這里需要將數據表中的一級菜單的 parentid 設置為 -1。

   最終界面展示

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM