1. 程式人生 > >基於MVC4+EasyUI的Web開發框架經驗總結(2)- 使用EasyUI的樹控制元件構建Web介面

基於MVC4+EasyUI的Web開發框架經驗總結(2)- 使用EasyUI的樹控制元件構建Web介面

最近花了不少時間在重構和進一步提煉我的Web開發框架上,力求在使用者體驗和介面設計方面,和Winform開發框架保持一致,而在Web上,我主要採用EasyUI的前端介面處理技術,走MVC的技術路線,在重構完善過程中,很多細節花費不少時間進行研究和提煉,一步步走過來,也積累了不少經驗,本系列將主要介紹我在進一步完善我的Web框架基礎上積累的經驗進行分享,本隨筆主要介紹使用EasyUI的樹控制元件構建Web介面的相關經驗。

在很多介面設計上,我們可能都需要引入樹列表控制元件,這個控制元件可以用zTree來實現,也可以用EasyUI的內建樹控制元件進行展示,由於歷史原因,我原來傾向於使用zTree,最新把它全部修改為EasyUI的樹控制元件,並進行了完善優化,發現程式碼更加簡潔明快,非常不錯。

1、在介面上使用EasyUI的樹控制元件

一般情況下,使用EasyUI的樹控制元件,程式碼很簡單,指令碼程式碼如下所示,主要就是通過呼叫url來獲得Json資料,然後就可以顯示了,通過onClick就可以響應使用者單擊節點的操作,每個節點有id, text, iconCls, checked,state,children等屬性。

1)樹控制元件的Json資料繫結

            $('#treeDept').tree({
                url: '/User/[email protected]["UserId"]',
                onClick: 
function (node) { loadData(node.id); } });

2)樹控制元件的摺疊和展開

樹控制元件的展開和摺疊,可以通過定義兩個通用的指令碼進行處理,如下所示。

        function expandAll(treeName) {
            var node = $('#' + treeName).tree('getSelected');
            if (node) {
                $('#' + treeName).tree('expandAll', node.target);
            }
            
else { $('#' + treeName).tree('expandAll'); } } function collapseAll(treeName) { var node = $('#' + treeName).tree('getSelected'); if (node) { $('#' + treeName).tree('collapseAll', node.target); } else { $('#' + treeName).tree('collapseAll'); } }

然後,在頁面載入完畢後,繫結指定的按鈕控制元件就可以了嗎,如下程式碼所示。

        //初始化物件
        $(document).ready(function () {
            //初始化機構分類
            initOUCategorys();

            //機構基礎資訊
            initDeptTreeview();
            $("#deptExpand").bind("click", function () {
                expandAll("treeDept");
            });
            $("#deptCollapse").bind("click", function () {
                collapseAll("treeDept");
            });                       

            $("#loading").center(); //loading的圖片顯示居中
        });

3)樹控制元件的複選框顯示

樹控制元件預設是沒有複選框的,它可以通過屬性checkbox設定讓它進行展示的,如下程式碼是我專案裡面的程式碼。

其中cascadeCheck是否讓樹控制元件級聯的,預設是級聯,也就是隻要父控制元件被選中,所有其子控制元件都會被選中,我們可以設定它為false,讓它不級聯,這樣在很多情況下是需要的。

            $('#treeFunctionView').tree({
                checkbox: true,
                cascadeCheck: false,
                url: '/Function/[email protected]["UserId"]',
                onClick: function (node) {
                    //
                }
            });

4)樹控制元件的全選和全不選擇

這個全部不選的特性,我找了很多文章,都沒有找到,其實後來才發現,我們對樹的節點理解有偏差,認識到後,實現起來也很容易。

如取消全部節點的選中狀態,程式碼如下所示。它的方法getChecked是返回所有的節點,而不是一個節點。它們把全部選中的節點放到一個結合裡面,不像Winform裡面,樹節點需要遞迴查詢,這裡只需要一個for迴圈就可以展開了,我這裡把所有勾選的節點,設定為非勾選狀態就可以實現取消全部樹節點勾選狀態了。

        function unCheckTree(tree) {
            var nodes = $('#' + tree).tree('getChecked');
            if (nodes) {
                for (var i = 0; i < nodes.length; i++) {
                    $('#' + tree).tree('uncheck', nodes[i].target);
                }
            }
        }

我們知道,很多樹控制元件,為了方便操作,都提供了一個全選或者全部不選的操作,這個在EasyUI的樹控制元件裡面,也是很容易實現的。這裡的getChildren和上面的意思類似,也是返回所有的子節點,不需要在進行遞迴,用一個for迴圈就可以遍歷全部節點和其下面的多級子節點了。也就是說,它是一個二維的資料,不用遞迴查詢。

        function checkAllTree(tree, checked) {
            var children = $('#' + tree).tree('getChildren');
            for (var i = 0; i < children.length; i++) {
                if (checked) {
                    $('#' + tree).tree('check', children[i].target);
                } else {
                    $('#' + tree).tree('uncheck', children[i].target);
                }
            }
        }

5)下拉列表的樹控制元件初始化

除了普通的樹列表,還有一種比較特殊的樹控制元件,就是在ComboTree,也就是在下拉列表中整合樹控制元件,它的操作和普通的樹控制元件差不多,很多事件屬性都一樣,它的使用程式碼如下所示。

        //初始化公司
        function initCompany() {
            $('#txtCompany_ID').combotree({
                url: '/User/[email protected]["UserId"]',
                valueField: 'id',
                textField: 'text',
                required: true,
                onClick: function (node) {
                    //
                }
            });
        }

2、樹控制元件的優化

1)普通的Json資料生成

前面說了,我們為了方便,一般使用Json資料和javascript打交道,而EasyUI的樹控制元件支援很好地的Json連結繫結,因此我們只需要在對應的控制器裡面實現json資料的生成即可,如果是一開始想要確定的Json資料,一般也是通過手工生成的居多,如下程式碼所示。

        public ActionResult GetTreeJson()
        {
            string folder = "/Content/JqueryEasyUI/themes/icons/customed/" + "organ.png";
            string leaf = "/Content/JqueryEasyUI/themes/icons/customed/" + "organ.png";
            string json = GetTreeJson(-1, folder, leaf);
            json = json.Trim(',');
            return Content(string.Format("[{0}]", json));
        }

        /// <summary>
        /// 遞迴獲取樹形資訊
        /// </summary>
        /// <param name="PID"></param>
        /// <returns></returns>
        private string GetTreeJson(int PID, string folderIcon, string leafIcon)
        {
            string condition = string.Format("PID={0}", PID);
            List<OUInfo> nodeList = BLLFactory<OU>.Instance.Find(condition);
            StringBuilder content = new StringBuilder();
            foreach (OUInfo model in nodeList)
            {
                int ParentID = (model.PID == -1 ? 0 : model.PID);
                //string tempMenu = string.Format("{{ id:{0}, pId:{1}, name:\"{2}\",icon:\"{3}\" }},", model.ID, ParentID, model.Name, imgsrc);
                string subMenu = this.GetTreeJson(model.ID, folderIcon, leafIcon);
                string parentMenu = string.Format("{{ \"id\":{0}, \"pId\":{1}, \"name\":\"{2}\" ", model.ID, ParentID, model.Name);
                if (string.IsNullOrEmpty(subMenu))
                {
                    if (!string.IsNullOrEmpty(leafIcon))
                    {
                        parentMenu += string.Format(",\"icon\":\"{0}\" }},", leafIcon);
                    }
                    else
                    {
                        parentMenu += "},";
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(folderIcon))
                    {
                        parentMenu += string.Format(",\"icon\":\"{0}\" }},", folderIcon);
                    }
                    else
                    {
                        parentMenu += "},";
                    }
                }

                content.AppendLine(parentMenu.Trim());
                content.AppendLine(subMenu.Trim());
            }

            return content.ToString().Trim();
        } 

上面的程式碼很好實現了根據資料庫結構的關係,生成Json資料,但是感覺部分硬編碼,湊出來的資料,始終感覺不太理想,如果我們要簡化,該如何操作呢?

2)簡潔美觀的Json資料生成

本小節繼續上面的議題,看如何簡化json的生成,因為我們需要很多這樣的json操作,如果採用上面的方法,我感覺很容易出錯,而且也不太美觀。為了解決這個問題,我們可以通過定義一個json資料的實體類,用來承載相關的資訊,如下定義所示。

    /// <summary>
    /// 定義EasyUI樹的相關資料,方便控制器生成Json資料進行傳遞
    /// </summary>
    [DataContract]
    [Serializable]
    public class EasyTreeData
    {
        /// <summary>
        /// ID
        /// </summary>
        [DataMember]
        public string id { get; set; }

        /// <summary>
        /// 節點名稱
        /// </summary>
        [DataMember]
        public string text { get; set; }
        
        /// <summary>
        /// 是否展開
        /// </summary>
        [DataMember]
        public string state  { get; set; }

        /// <summary>
        /// 圖示樣式
        /// </summary>
        [DataMember]
        public string iconCls { get; set; }


        /// <summary>
        /// 子節點集合
        /// </summary>
        [DataMember]
        public List<EasyTreeData> children { get; set; }
        
        /// <summary>
        /// 預設建構函式
        /// </summary>
        public EasyTreeData() 
        {
            this.children = new List<EasyTreeData>();
            this.state = "open";
        }

        /// <summary>
        /// 常用建構函式
        /// </summary>
        public EasyTreeData(string id, string text, string iconCls = "", string state = "open")
            : this()
        {
            this.id = id;
            this.text = text;
            this.state = state;
            this.iconCls = iconCls;
        }

        /// <summary>
        /// 常用建構函式
        /// </summary>
        public EasyTreeData(int id, string text, string iconCls = "", string state = "open")
            : this()
        {
            this.id = id.ToString();
            this.text = text;
            this.state = state;
            this.iconCls = iconCls;
        }
    }

然後,我們在需要生成Json資料的地方,使用這個實體類進行承載,然後把它列表生成Json就可以了,很簡單了,呵呵。

        /// <summary>
        /// 根據使用者獲取對應人員層次的樹Json
        /// </summary>
        /// <param name="deptId">使用者所在部門</param>
        /// <returns></returns>
        public ActionResult GetUserTreeJson(int deptId)
        {
            List<EasyTreeData> treeList = new List<EasyTreeData>();
            treeList.Insert(0, new EasyTreeData(-1, "無"));

            List<UserInfo> list = BLLFactory<User>.Instance.FindByDept(deptId);
            foreach (UserInfo info in list)
            {
                treeList.Add(new EasyTreeData(info.ID, info.FullName, "icon-user"));
            }

            string json = ToJson(treeList);
            return Content(json);
        }

如果需要遞迴的操作,一樣的方式處理就可以了。

        /// <summary>
        /// 獲取使用者的部門樹結構(分級需要)
        /// </summary>
        /// <param name="userId">使用者ID</param>
        /// <returns></returns>
        public ActionResult GetMyDeptTreeJson(int userId)
        {
            StringBuilder content = new StringBuilder();
            UserInfo userInfo = BLLFactory<User>.Instance.FindByID(userId);
            if (userInfo != null)
            {
                OUInfo groupInfo = GetMyTopGroup(userInfo);
                if (groupInfo != null)
                {
                    List<OUNodeInfo> list = BLLFactory<OU>.Instance.GetTreeByID(groupInfo.ID);

                    EasyTreeData treeData = new EasyTreeData(groupInfo.ID, groupInfo.Name, GetIconcls(groupInfo.Category));
                    GetTreeDataWithOUNode(list, treeData);

                    content.Append(base.ToJson(treeData));
                }
            }
            string json = string.Format("[{0}]", content.ToString().Trim(','));
            return Content(json);
        }

上面使用EasyTreeData來承載資料,然後構建列表,其本身就是一個多層級的樹物件,然後一個ToJson的方法就可以把列表物件完美轉換為Jason資料了。

這裡的ToJson,主要就是呼叫JavaScriptSerializer 物件進行的操作,如下所示。

        /// <summary>
        /// 把物件為json字串
        /// </summary>
        /// <param name="obj">待序列號物件</param>
        /// <returns></returns>
        protected string ToJson(object obj)
        {
            string jsonData = (new JavaScriptSerializer()).Serialize(obj);
            return jsonData;
        }

3、樹控制元件效果展示

在介紹如何使用它之後,我們來看看我幾個場景中使用樹控制元件進行的展示效果,方便我們加深上面EasyUI樹控制元件使用的瞭解。

1)組織機構列表如下所示:

2)角色樹列表展示

3)功能樹列表展示

4)選單樹列表展示

5)登陸日誌樹列表展示

6)下拉列表樹展示

  

    

基於MVC4+EasyUI的Web開發框架的系列文章:

相關推薦

基於MVC4+EasyUIWeb開發框架經驗總結4--使用圖表控制元件Highcharts

在我們做各種應用的時候,我們可能都會使用到圖表統計,以前接觸過一些不同的圖表控制元件,在無意中發現了圖表控制元件Highcharts,其強大的功能和豐富的互動效果,令人難以忘懷。本篇主要介紹在Web開發中使用圖表控制元件Highcharts,以及對其進行統一漢化等操作,讓我們的程式功能更加豐富,內容更加美觀。

基於MVC4+EasyUIWeb開發框架經驗總結2- 使用EasyUI控件構建Web界面

set 應用 get ember trim ase str zab ble http://www.cnblogs.com/wuhuacong/p/3669575.html 最近花了不少時間在重構和進一步提煉我的Web開發框架上,力求在用戶體驗和界面設計方面,和Winfor

基於MVC4+EasyUIWeb開發框架經驗總結3- 使用Json實體類構建選單資料

最近花了不少時間在重構和進一步提煉我的Web開發框架上,力求在使用者體驗和介面設計方面,和Winform開發框架保持一致,而在Web上,我主要採用EasyUI的前端介面處理技術,走MVC的技術路線,在重構完善過程中,很多細節花費不少時間進行研究和提煉,一步步走過來,也積累了不少經驗,本系列將主要介紹我在進一步

基於MVC4+EasyUIWeb開發框架經驗總結2- 使用EasyUI控制元件構建Web介面

最近花了不少時間在重構和進一步提煉我的Web開發框架上,力求在使用者體驗和介面設計方面,和Winform開發框架保持一致,而在Web上,我主要採用EasyUI的前端介面處理技術,走MVC的技術路線,在重構完善過程中,很多細節花費不少時間進行研究和提煉,一步步走過來,也積累了不少經驗,本系列將主要介紹我在進一步

基於Metronic的Bootstrap開發框架經驗總結2--列表分頁處理和外掛JSTree的使用

在上篇《基於Metronic的Bootstrap開發框架經驗總結(1)-框架總覽及選單模組的處理》介紹了Bootstrap開發框架的一些基礎性概括,包括總體介面效果,以及佈局、選單等內容,本篇繼續這一主題,介紹頁面內容常用到的資料分頁處理,以及Bootstrap外掛JSTree的使用。在資料的介面顯示當中,表

基於MVC4+EasyUIWeb開發框架經驗總結5--使用HTML編輯控件CKEditor和CKFinder

err config 兩個 腳本 web開發 upload asp 正常 初始 http://www.cnblogs.com/wuhuacong/p/3780356.html Web開發上有很多HTML的編輯控件,如CKEditor、kindeditor等等,很多都做的很

基於MVC4+EasyUIWeb開發框架經驗總結6--在頁面中應用下拉列表的處理

ica new web開發 don ext images 如果 bob 獲取 http://www.cnblogs.com/wuhuacong/p/3840321.html 在很多Web界面中,我們都可以看到很多下拉列表的元素,有些是固定的,有些是動態的;有些是字典內容,

基於MVC4+EasyUIWeb開發框架經驗總結8--實現Office文檔的預覽

討論 off info code .cn viewer 存在 nco app http://www.cnblogs.com/wuhuacong/p/3871991.html 基於MVC4+EasyUI的Web開發框架經驗總結(8)--實現Office文檔的預覽

基於MVC4+EasyUIWeb開發框架經驗總結1-利用jQuery Tags Input 外掛顯示選擇記錄

最近花了不少時間在重構和進一步提煉我的Web開發框架上,力求在使用者體驗和介面設計方面,和Winform開發框架保持一致,而在Web上,我主要採用EasyUI的前端介面處理技術,走MVC的技術路線,在重構完善過程中,很多細節花費不少時間進行研究和提煉,一步步走過來,也積累了不

基於MVC4+EasyUIWeb開發框架經驗總結13--DataGrid控制元件實現自動適應寬頻高度

在預設情況下,EasyUI的DataGrid好像都沒有具備自動寬度的適應功能,一般是指定畫素寬度的,但是使用的人員計算機的螢幕解析度可能不一樣,因此導致有些地方顯示太大或者太小,總是不能達到好的預期效果,如果DataGrid能夠根據視窗尺寸進行伸縮,效果應該好很多。本文主要介紹DataGrid控制元件實現自動

基於MVC4+EasyUIWeb開發框架經驗總結7--實現省份、城市、行政區三者聯動

為了提高客戶體驗和進行一些技術探索,現在正準備把我自己的客戶關係管理系統CRM在做一個Web的版本,因此對基於MVC的Web介面繼續進行一些研究和優化,力求在功能和介面上保持和Winform一致,本文主要介紹在我的CRM系統中用到的全國省份、城市、行政區三者的兩種效果,在Winform上實現沒問題,在Web上

基於MVC4+EasyUIWeb開發框架經驗總結6--在頁面中應用下拉列表的處理

在很多Web介面中,我們都可以看到很多下拉列表的元素,有些是固定的,有些是動態的;有些是字典內容,有些是其他表裡面的名稱欄位;有時候引用的是外來鍵ID,有時候引用的是名稱文字內容;正確快速使用下拉列表的處理,可以提高我們程式介面的美觀性和友好型,本文主要介紹在我的Web開發框架以及相關的擴充套件Web應用中用

基於MVC4+EasyUIWeb開發框架經驗總結14--自動生成圖示樣式檔案和圖示的選擇操作

在很多Web系統中,一般都可能提供一些圖示的選擇,方便配置按鈕,選單等介面元素的圖示,從而是Web系統介面看起來更加美觀和協調。但是在系統中一般內建的圖示樣式相對比較有限,而且硬編碼寫到樣式表裡面,這樣給我們擴充套件使用有很多的不方便。基於這個原因,我想如果能夠獨立一個模組,自動根據圖示生成圖示CSS樣式檔案

基於MVC4+EasyUIWeb開發框架經驗總結9--在Datagrid裡面實現外來鍵欄位的轉義操作

我們在使用EasyUI的時候,很多情況下需要使用到表格控制元件datagrid,這個控制元件控制元件非常強大,使用起來很簡潔,但是我在使用中,發現對於一個表裡面的外來鍵欄位進行轉義,並顯示引用表的一些名稱的操作,卻顯得比較難以實現,找了很多資料,基本上沒有找到對應的解決方案。本文主要介紹我對這種外來鍵欄位轉義

基於MVC4+EasyUIWeb開發框架經驗總結11--使用Bundles處理簡化頁面程式碼

在Web開發的時候,我們很多時候,需要引用很多CSS檔案、JS檔案,隨著使用更多的外掛或者獨立樣式檔案,可能我們的Web介面程式碼會越來越臃腫,看起來也很累贅,在MVC裡面提供了一個Bundle的物件,用來簡化頁面程式碼非常方便,本文主要介紹在我的MVC框架裡面,如何使用bundles來簡化頁面的程式碼的。

基於MVC4+EasyUIWeb開發框架經驗總結8--實現Office文件的預覽

在部落格園很多文章裡面,曾經有一些介紹Office文件預覽檢視操作的,有些通過轉為PDF進行檢視,有些通過把它轉換為Flash進行檢視,但是過程都是曲線救國,真正能夠簡潔方便的實現Office文件的預覽的還是比較少,這裡的Office文件包括了Word、Excel、PPT文件。本文介紹兩種方式,一種方式是通過

基於MVC4+EasyUIWeb開發框架經驗總結5--使用HTML編輯控制元件CKEditor和CKFinder

Web開發上有很多HTML的編輯控制元件,如CKEditor、kindeditor等等,很多都做的很好,本文主要介紹在MVC介面裡面,CKEditor的配置和使用。CKEditor的前身是FCKEditor,隨著它的更新,上傳圖片的功能被分離出去了,現在如果需要實現上傳圖片,要麼自己寫程式碼或者採用其他上傳控

基於MVC4+EasyUIWeb開發框架經驗總結10--在Web介面上實現資料的匯入和匯出

資料的匯入匯出,在很多系統裡面都比較常見,這個匯入匯出的操作,在Winform裡面比較容易實現,我曾經在之前的一篇文章《Winform開發框架之通用資料匯入匯出操作》介紹了在Winform裡面的通用匯入匯出模組的設計和開發過程,但在Web上我們應該如何實現呢?本文主要介紹利用MVC4+EasyUI的特點,並結

基於MVC4+EasyUIWeb開發框架經驗總結12--利用Jquery處理資料互動的幾種方式

在基於MVC4+EasyUI的Web開發框架裡面,大量採用了Jquery的方法,對資料進行請求或者提交,方便頁面和伺服器後端進行資料的互動處理。本文主要介紹利用Jquery處理資料互動的幾種方式,包括獲取資料並顯示,插入新資料到伺服器,更新資料,刪除資料等操作。 1、利用Jquery獲取資料並顯示 為了順

基於Metronic的Bootstrap開發框架經驗總結17-- 使用 summernote插件實現HTML文檔的編輯和圖片插入操作

系統 cat 寫入 視頻 編寫 查看 absolute upload form 在很多場合,我們需要在線編輯HTML內容,然後在頁面上或者其他終端上(如小程序、APP應用等)顯示,編輯HTML內容的插件有很多,本篇介紹基於Bootstrap的 summernote插件實現H