Ext Js簡單Tree創建及其異步加載


對於Ext Js的樹的使用也是比較多的,本篇分享簡單的Tree的創建及其樹的異步加載處理。

1.簡單TreePanel的創建

function creatTree() {//創建簡單的樹
    //節點集合創建
    var rootNode = new Ext.tree.TreeNode({ id: 'root', text: '根節點', expanded: true }); //只展開根節點(只展開某節點)
    var node1 = new Ext.tree.TreeNode({ id: 'node1', text: 'Node1', leaf: true }); //為葉子節點
    var node2 = new Ext.tree.TreeNode({ id: 'node2', text: 'Node2' });
    var node3 = new Ext.tree.TreeNode({ id: 'node3', text: 'Node3', expanded: true });

    var arrNodes = [//節點集合
            new Ext.tree.TreeNode({ id: 'nodeOne', text: 'NodeOne' }),
            new Ext.tree.TreeNode({ id: 'nodeTwo', text: 'NodeTwo' }),
            new Ext.tree.TreeNode({ id: 'nodeThree', text: 'NodeThree' })
            ];
    var arrayNodes = [new Ext.tree.TreeNode({ text: 'nodeOne' }), new Ext.tree.TreeNode({ text: 'nodeTwo' })];

    node2.appendChild(arrayNodes); //將集合節點添加到對應的節點
    node3.appendChild(arrNodes);

    rootNode.appendChild(node1); //根節點添加對應的節點
    rootNode.appendChild(node2);
    rootNode.appendChild(node3);

    //也可以如下添加節點集合
    //rootNode.appendChild([node1, node2, node3]); //添加節點集合

    var treePanel = new Ext.tree.TreePanel({
        renderTo: Ext.getBody(), width: 150, root: rootNode,
        animate: true, //是否動畫
        enableDD: true, //是否拖拽操作
        useArrows: true, //使用Vista-style箭頭
        autoScroll: true, //是否自動滾動條
        containerScroll: true//向ScrollManager注冊此容器 
    });
}

2.簡單TreePanel的使用

//簡單的樹的練習
function treeTest() {
    var rootNode = new Ext.tree.TreeNode({//創建根節點
        id: 'root', text: '樹的根', nodeType: 'async'
    });

    rootNode.appendChild(new Ext.tree.TreeNode({ id: 'node1', text: 'Node1', leaf: true })); //是葉子節點,將不能添加子節點
    rootNode.appendChild(new Ext.tree.TreeNode({ id: 'node2', text: 'Node2', leaf: true }));

    var node3 = new Ext.tree.TreeNode({ id: 'node3', text: 'Node3' }); //創建節點3
    var arrNodes = [//節點集合
            new Ext.tree.TreeNode({ id: 'node30', text: 'Node30' }),
            new Ext.tree.TreeNode({ id: 'node31', text: 'Node31' }),
            new Ext.tree.TreeNode({ id: 'node32', text: 'Node32' })];
    node3.appendChild(arrNodes); //將節點集合添加到節點3中
    rootNode.appendChild(node3); //將節點3添加到根節點中

    var treePanel = new Ext.tree.TreePanel({//創建節點樹對象
        renderTo: Ext.getBody(), root: rootNode, width: 200, animate: true, enableDD: true //animate動畫效果,enableDD拖拽效果
    });

    //tree.getRootNode().expand(); //某個節點展開
    //node.expand(true);
    treePanel.expandAll(); //展開樹下的所有節點

    //該節點下的所有子節點都觸發
    //node3.eachChild(function () { alert('TT') });

    //某個節點(節點3)點擊事件,鼠標位置
    //node3.on('click', function (node, e) { Ext.Msg.alert('信息提示', '你點擊' + node.text + '的節點' + e.getXY()) });

    treePanel.on('click', function (node) {//所有節點都觸發改事件
        if (node.hasChildNodes()) {//判斷該節點是否含有子節點
            var msg = node.text + '有子節點:';

            var childNodes = node.childNodes; //取得該節點下的所有子節點
            for (var i = 0; i < childNodes.length; i++) {//遍歷子節點集合
                msg += childNodes[i].text + '|'; //拼接節點集合文本信息
            }
            Ext.Msg.alert('信息提示', msg);
        } else {
            if (node.isLeaf()) {//判斷該節點是否為葉子節點
                Ext.Msg.alert('信息提示', '你點擊的是葉子節點:' + node.text);
            }
        }
    })
}

3.簡單前台Ext Js對樹的增刪改

//前台ExtJs操作對樹的增刪改操作
function treeOperation() {
    var root = new Ext.tree.TreeNode({ text: '根節點' });
    var treePanel = new Ext.tree.TreePanel({
        width: 300, height: 600, renderTo: Ext.getBody(), root: root, id: 'testTree',
        tbar: [
                        { text: '添加同級節點', handler: function () { singleNodeInfo('addSibling', 'testTree'); } },
                        { text: '添加下級節點', handler: function () { singleNodeInfo('addChild', 'testTree'); } },
                        { text: '修改節點', handler: function () { singleNodeInfo('update', 'testTree'); } },
                        { text: '刪除節點', handler: function () { removeNode('testTree'); } }
                      ]
    });

    //treePanel.on('contextmenu', function (node, e) { var myMenu = createMenu(); node.select(); myMenu.showAt(e.getPoint()); });
    //對於節點內容的操作,也可以使用Ext.Msg.prompt來處理,如下:
    //Ext.msg.prompt('請輸入節點名稱', '節點名稱:', function (btn, text) { if (btn == 'ok') { alert(text); } });
}
function removeNode(treePanelID) {//刪除節點,參數:樹ID
    var treePanel = Ext.getCmp(treePanelID);
    var selNode = treePanel.selModel.getSelectedNode();
    if (selNode == null) {
        Ext.Msg.alert('信息提示', '請選擇你要刪除的節點!');
        return;
    }
    if (!selNode.hasChildNodes()) {//是否包含子節點
        var removeNode = selNode.remove(); //其父節點移除自己
        Ext.Msg.alert('信息提示', '你移除了節點' + removeNode.text);
    }
    else {
        Ext.Msg.confirm('信息提示', '該節點為父節點,一並刪除?', function (btn) {
            if (btn == 'yes') {
                selNode.removeAll(); //連同下面的子節點一起刪除
            }
        });
    }
}
function AddAndUpdateNode(type, selNode, nodeName) {//添加\修改節點,參數:操作類型\選中節點\節點名字
    if (selNode != null) {
        switch (type) {
            case 'addChild': //添加子節點
                var addNode = new Ext.tree.TreeNode({ text: nodeName });
                selNode.appendChild(addNode);
                break;
            case 'addSibling': //添加同級節點
                var addNode = new Ext.tree.TreeNode({ text: nodeName });
                var parentNode = selNode.parentNode.appendChild(addNode);
                break;
            case 'update': //修改文本內容
                selNode.setText(nodeName);
                break;
        }
        selNode.expand(); //選中節點展開
    }
}
function singleNodeInfo(type, treeId) {//參數:操作類型,treePanel對象
    var treePanel = Ext.getCmp(treeId);
    var selNode = treePanel.selModel.getSelectedNode(); //獲取選中的節點
    if (selNode == null) {
        Ext.Msg.alert('信息提示', '請選擇一個節點');
        return;
    }
    var win = new Ext.Window({//彈出信息對話框
        title: '添加修改節點', width: 230, height: 100,
        bodyStyle: "padding-top:10px",
        items: [
                    { xtype: 'label', text: '節點名字:', width: 200 },
                    { xtype: 'textfield', id: 'txtNodeName' }
                ],
        bbar: [
                    { text: '保存', handler: function () {
                        var nodeName = Ext.getCmp('txtNodeName').getValue();
                        AddAndUpdateNode(type, selNode, nodeName); //更新數據
                        Ext.Msg.alert('信息提示', '保存成功!'); win.close();
                    }
                    }, '->',
                    { text: '取消', handler: function () { win.close(); } }
                    ]
    });
    if (type == "update") {
        Ext.getCmp('txtNodeName').setValue(selNode.text);
    }
    win.show(); //顯示信息
}

//你也可以試試添加一個右鍵菜單對節點進行操作
function createMenu() {
    var myMenu = new Ext.menu.Menu(
                    { xtype: 'button', text: '添加節點', handler: function (tree) { Ext.Msg.alert('信息提示', '添加節點'); } },
                    { xtype: 'button', text: '下級節點', handler: function () { Ext.Msg.alert('信息提示', '下級節點'); } },
                    { xtype: 'button', text: '修改節點', handler: function () { Ext.Msg.alert('信息提示', '修改節點'); } },
                    { xtype: 'button', text: '刪除節點', handler: function () { Ext.Msg.alert('信息提示', '刪除節點'); } }
                    );
    return myMenu;
}

4.簡單樹的異步加載(需要創建異步節點Ext.tree.AsyncTreeNode並使用Ext.tree.TreeLoader加載)(注意對於葉子節點的指定)

function treeAsyncTest() {//樹的異步加載,一次加載對應的數據
    var treePanel = new Ext.tree.TreePanel({
        el: 'divTree', //渲染divID
        width: 150, height: 300, animate: true, enableDD: true, rootVisible: true,
        loader: new Ext.tree.TreeLoader({ url: 'TestTreeAjx.ashx', baseParams: { Option: 'GetAllData'} })
    });
    var rootNode = new Ext.tree.AsyncTreeNode({ text: '根節點' });

    treePanel.setRootNode(rootNode);
    treePanel.render(); //進行渲染
    rootNode.expand(true, true); //參數1:展開所有節點;參數2:啟動動畫效果
    //這樣操作完你會發現所有的節點可能會無限的延展下去,
    //是因為數據引起的,在加載時,傳出的數據指定最后一級為葉子節點就可以了
}

5.針對不同的節點異步加載不同的節點數據(注意對於葉子節點的指定)

function treeNodeAsync() {//根據不同的節點值,獲取不同的加載數據(可以是節點ID\節點文本等等)
    var rootNode = new Ext.tree.AsyncTreeNode({ text: 'rootNode' });
    var treePanel = new Ext.tree.TreePanel({
        el: 'divTree',
        width: 150, height: 300, animate: true, enableDD: true, rootVisible: true,
        listeners: {
            'beforeload': function (node) {//按這種形式傳遞的數據,不指定最后的葉子節點的話,會遍歷每個節點,性能不好(如果需要,在對應節點下指定葉子節點)
                node.loader = new Ext.tree.TreeLoader({ url: 'TestTreeAjx.ashx', baseParams: { Option: 'GetNodeData', NodeText: node.text} })
            }
        }
    });

    treePanel.setRootNode(rootNode);
    //這里可以試試對於節點展開和非展開所有節點的數據加載情況
    //一次展開所有節點,會一次遍歷完畢加載數據;不展開節點折疊起來,會在對應節點展開需加載時加載對應數據
    rootNode.expand(false, true);
    treePanel.render();
}

6.其Ajax請求頁面TestTreeAjx.ashx代碼(簡單的模擬數據)

namespace WebExtJS.WebTest
{
    /// <summary>
    /// TestTreeAjx 的摘要說明
    /// </summary>
    public class TestTreeAjx : IHttpHandler
    {
        private static IDictionary<int, List<Node>> dic = null;
        public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";

            string strOption = context.Request["Option"] != null ? context.Request["Option"].ToString() : string.Empty;
            string nodeText = context.Request["NodeText"] != null ? context.Request["NodeText"].ToString() : string.Empty;
            string strMessage = string.Empty;

            dic = GetData();

            switch (strOption)
            {
                case "GetAllData": strMessage = GetAllData(dic); break;
                case "GetNodeData": strMessage = GetNodeData(nodeText); break;
                default: break;
            }

            context.Response.Write(strMessage);
            context.Response.End();
        }

        /// <summary>
        /// 獲取全部的數據
        /// </summary>
        /// <returns></returns>
        private string GetAllData()
        {
            string data = "[{text:'Node1',leaf:true},"
              + "{text:'Node2',children:[{text:'Node20',leaf:true},{text:'Node21',leaf:true}]},"
              + "{text:'Node3',children:[{text:'Node30',leaf:true},{text:'Node31',leaf:true},{text:'Node32',leaf:true}]}]";
            return data;
        }

        /// <summary>
        /// 根據不同的節點文本獲取對應的節點
        /// </summary>
        /// <param name="nodeText"></param>
        /// <returns></returns>
        private string GetNodeData(string nodeText)
        {
            string json = string.Empty;

            switch (nodeText)
            {//指定葉子節點遍歷非葉子節點(如果在其父節點指定為葉子節點,將不會加載對應的節點數據)
                case "rootNode": json = "[{text:'Node1',leaf:true},{text:'Node2'},{text:'Node3'}]"; break;
                case "Node2": json = "[{text:'Node20',leaf:true},{text:'Node21',leaf:true}]"; break;
                case "Node3": json = "[{text:'Node30',leaf:true},{text:'Node31',leaf:true},{text:'Node32',leaf:true}]"; break;
            }

            //switch (nodeText)
            //{//不指定葉子節點遍歷每一個節點
            //    case "rootNode": json = "[{text:'Node1'},{text:'Node2'},{text:'Node3'}]"; break;
            //    case "Node2": json = "[{text:'Node20'},{text:'Node21'}]"; break;
            //    case "Node3": json = "[{text:'Node30'},{text:'Node31'},{text:'Node32'}]"; break;
            //}

            return json;
        }
        
        /// <summary>
        /// 簡單字典模擬數據
        /// </summary>
        /// <returns></returns>
        private IDictionary<int, List<Node>> GetData()
        {
            IDictionary<int, List<Node>> dic = new Dictionary<int, List<Node>>();
            List<Node> nodeRoot = new List<Node>();
            List<Node> Node1 = new List<Node> { new Node(10, "Node10") };
            List<Node> Node2 = new List<Node> { new Node(20, "Node20"), new Node() { NodeID = 21, NodeName = "Node21" }, new Node() { NodeID = 22, NodeName = "Node22" } };
            List<Node> Node3 = new List<Node> { new Node(30, "Node30"), new Node(31, "Node31"), new Node(32, "Node32"), new Node(33, "Node33") };

            dic.Add(0, nodeRoot);//處理根節點
            dic.Add(1, Node1);
            dic.Add(2, Node2);
            dic.Add(3, Node3);

            return dic;
        }

        /// <summary>
        /// 遍歷拼接,獲取全部數據
        /// </summary>
        /// <param name="dic"></param>
        /// <returns></returns>
        private string GetAllData(IDictionary<int, List<Node>> dic)
        {
            string json = string.Empty;
            json = "[";
            if (dic.Count > 0)
            {
                for (int i = 0; i < dic.Count; i++)
                {
                    List<Node> tempNode;
                    if (dic[i].Count == 0)//根節點判斷
                    {
                        continue;
                    }
                    else
                    {
                        tempNode = dic[i];
                    }

                    if (tempNode.Count == 1)//只有一個葉子節點
                    {
                        json += "{text:'" + tempNode[0].NodeName + "'},";
                    }
                    else
                    {
                        json += "{text:'" + tempNode[0].NodeName + "',children:[";
                        for (int j = 1; j < tempNode.Count; j++)//對其葉子節點遍歷
                        {
                            json += "{text:'" + tempNode[j].NodeName + "',leaf:true},";
                        }
                        if (json.IndexOf(',') > 0)
                        {
                            json = json.Substring(0, json.LastIndexOf(','));
                        }
                        json += "]},";//閉合該節點
                    }
                }

            }
            if (json.IndexOf(',') > 0)
            {
                json = json.Substring(0, json.LastIndexOf(','));
                json += "]";
            }
            return json;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }

    public class Node
    {
        public Node() { }
        public Node(int nodeID, string nodeName)
        {
            this.NodeID = nodeID;
            this.NodeName = nodeName;
        }
        public int NodeID;
        public string NodeName;
    }
}

 


免責聲明!

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



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