最近做一個項目,開始接觸EasyUI,感覺很強大,很適合我這種對前台不是很感冒的人。在學習Tree的過程中,感覺網上的資料挺亂的,很多只是把EasyUI API 抄了一遍。現在把最近這段時間的學到的,給大家分享一下吧,也請大家提意見共同研究。廢話不多說了,要實現全動態生成無限級Tree。
1.最終的效果圖,可以實現無限分層。
2.數據庫表的生成代碼:
1 CREATE TABLE [dbo].[Tree]( 2 [ID] [int] IDENTITY(1,1) NOT NULL, 3 [CityName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, 4 [ParentID] [int] NULL, 5 [State] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, 6 [Url] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL 7 ) ON [PRIMARY]
說明:這個是EasyUI tree的數據庫表生成代碼。對應的字段有ID,CityName,ParentID,State,Url。其中ParentID是父節點ID,Url是指向的頁面。
3. EasyUI Tree需要的的數據格式要符合json。根據EasyUI Tree的API 中常用屬性,我們來制作.NET中的Model,先來看代碼,后面說明。
1 namespace MvcDemo.Model 2 { 3 public class JsonTree 4 { 5 private int _id; 6 private string _text; 7 private string _state="open"; 8 private Dictionary<string, string> _attributes=new Dictionary<string, string>(); 9 private object _children; 10 11 public int id 12 { 13 get { return _id; } 14 set { _id = value; } 15 } 16 public string text 17 { 18 get { return _text; } 19 set { _text = value; } 20 } 21 public string state 22 { 23 get { return _state; } 24 set { _state = value; } 25 } 26 public Dictionary<string, string> attributes 27 { 28 get { return _attributes; } 29 set { _attributes = value; } 30 } 31 public object children 32 { 33 get { return _children; } 34 set { _children = value; } 35 } 36 } 37 }
說明(從EasyUI 的API中復制):
-
id:節點ID,對加載遠程數據很重要。
-
text:顯示節點文本。
-
state:節點狀態,'open' 或 'closed',默認:'open'。在設置為'closed'的時候,當前節點的子節點將會從遠程服務器加載他們。
-
attributes: 被添加到節點的自定義屬性。(Url屬性就在這個里面,用Dictionary可以方便的擴展attribute。)
-
children: 一個節點數組聲明了若干節點。(這個是子節點,它擁有所有的父節點屬性)
children 類型為Object ,如果把children也定義為JsonTree類型,形成嵌套類,但是實例化的時候則會出現死循環問題,一直沒有解決,如果哪位知道如何解決,可以給我留言。如果對Object不明白,可以參考微軟MSDN。
4. 從數據庫得到的DataTable轉成成EasyUI所需要的對象結合,下面也是本文的核心代碼
1 namespace MvcDemo.Common 2 { 3 public class EasyUITree 4 { 5 public List<JsonTree> initTree(DataTable dt) 6 { 7 DataRow[] drList = dt.Select("parentid=0"); 8 List<JsonTree> rootNode = new List<JsonTree>(); 9 foreach (DataRow dr in drList) 10 { 11 JsonTree jt = new JsonTree(); 12 jt.id = int.Parse(dr["id"].ToString()); 13 jt.text = dr["cityname"].ToString(); 14 jt.state = dr["state"].ToString(); 15 jt.attributes = CreateUrl(dt, jt); 16 jt.children = CreateChildTree(dt, jt); 17 rootNode.Add(jt); 18 } 19 return rootNode; 20 } 21 22 private List<JsonTree> CreateChildTree(DataTable dt, JsonTree jt) 23 { 24 int keyid = jt.id; //根節點ID 25 List<JsonTree> nodeList = new List<JsonTree>(); 26 DataRow[] children = dt.Select("Parentid='" + keyid + "'"); 27 foreach (DataRow dr in children) 28 { 29 JsonTree node = new JsonTree(); 30 node.id = int.Parse(dr["id"].ToString()); 31 node.text = dr["cityname"].ToString(); 32 node.state = dr["state"].ToString(); 33 node.attributes = CreateUrl(dt, node); 34 node.children = CreateChildTree(dt, node); 35 nodeList.Add(node); 36 } 37 return nodeList; 38 } 39 40 41 private Dictionary<string, string> CreateUrl(DataTable dt, JsonTree jt) //把Url屬性添加到attribute中,如果需要別的屬性,也可以在這里添加 42 { 43 Dictionary<string, string> dic = new Dictionary<string, string>(); 44 int keyid = jt.id; 45 DataRow[] urlList = dt.Select("id='" + keyid + "'"); 46 string url = urlList[0]["Url"].ToString(); 47 dic.Add("url", url); 48 return dic; 49 } 50 } 51 }
說明:上面這三段代碼,最主要的是前兩段遞歸生成樹。先生成根節點,然后在依次生成此節點的子節點。CreateUrl方法生成EasyUI Tree所需要的結構。
5.在Controller中調用initTree方法,獲得對象集合,然后把集合轉變成json對象
1 public ActionResult JsonTreeTest() 2 { 3 EasyUIBLL bll = new EasyUIBLL(); 4 EasyUITree EUItree=new EasyUITree(); 5 DataTable dt = bll.GetTable(); 6 List<JsonTree> list = EUItree.initTree(dt); 7 var json = JsonConvert.SerializeObject(list); //把對象集合轉換成Json 8 return Content(json); 9 }
說明:“var json = JsonConvert.SerializeObject(list);” 此步驟需要用 Newtonsoft.Json.dll 下載,使用這個動態連接庫,不用再為拼接json字符串而苦惱,可以把更多經歷放在邏輯上,注意記得添加引用 “using Newtonsoft.Json;”
6.前台的代碼:
$('#tree').tree({ url: '/EasyUI/JsonTreeTest', checkbox:true });
前台就采用EasyUI提供的方法。url值就是controller中對應的方法。
7.獲得到的Json格式數據: 由於比較長,此處折疊起來了

1 [ 2 { 3 "id": 1, 4 "text": "中國", 5 "state": "open", 6 "attributes": { 7 "url": "" 8 }, 9 "children": [ 10 { 11 "id": 2, 12 "text": "北京", 13 "state": "open", 14 "attributes": { 15 "url": "" 16 }, 17 "children": [ 18 { 19 "id": 8, 20 "text": "海淀區", 21 "state": "", 22 "attributes": { 23 "url": "" 24 }, 25 "children": [] 26 }, 27 { 28 "id": 9, 29 "text": "朝陽區", 30 "state": "", 31 "attributes": { 32 "url": "" 33 }, 34 "children": [] 35 } 36 ] 37 }, 38 { 39 "id": 3, 40 "text": "上海", 41 "state": "open", 42 "attributes": { 43 "url": "" 44 }, 45 "children": [] 46 }, 47 { 48 "id": 4, 49 "text": "河南", 50 "state": "open", 51 "attributes": { 52 "url": "" 53 }, 54 "children": [ 55 { 56 "id": 5, 57 "text": "鄭州", 58 "state": "open", 59 "attributes": { 60 "url": "" 61 }, 62 "children": [] 63 }, 64 { 65 "id": 6, 66 "text": "焦作", 67 "state": "open", 68 "attributes": { 69 "url": "" 70 }, 71 "children": [ 72 { 73 "id": 7, 74 "text": "解放區", 75 "state": "open", 76 "attributes": { 77 "url": "" 78 }, 79 "children": [ 80 { 81 "id": 10, 82 "text": "建設路", 83 "state": "", 84 "attributes": { 85 "url": "" 86 }, 87 "children": [] 88 } 89 ] 90 } 91 ] 92 } 93 ] 94 } 95 ] 96 } 97 ]
8.提示一下,后台所有的轉換,都是為了返回EasyUI所需要的Json格式。需要注意的是:Json格式中,所有屬性的字母都是小寫的,所以在封裝JsonTree對象時記得小寫,避免不必要的麻煩。
9.由於本人的語言表達能力有限,如果有什么地方沒有說明白,可以加我QQ:2413660559 ,也歡迎給我指出文中的錯誤。
總結:采用這種方式,可以從數據庫讀取出數據,通過遞歸生成樹形對象,再把樹形對象轉成Json對象,傳遞給前台顯示,這種方式,代碼的整齊度大大提高,面向對象,易於擴展。
轉載請標明出處。