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

來源:互聯網
上載者:User

標籤:ber   zab   出錯   如何使用   擷取   cascade   func   轉換   img   

http://www.cnblogs.com/wuhuacong/p/3669575.html

最近花了不少時間在重構和進一步提煉我的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開發架構經驗總結(2)- 使用EasyUI的樹控制項構建Web介面

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.