符合EasyUI中Tree的Json格式,我們先看一下,格式是如何的
[{ "id":1, "text":"My Documents", "children":[{ "id":22, "text":"Photos", "state":"closed", "children":[{ "id":111, "text":"Friend" },{ "id":112, "text":"Wife" },{ "id":113, "text":"Company" }] },{ "id":12, "text":"Program Files", "children":[{ "id":121, "text":"Intel" },{ "id":122, "text":"Java", "attributes":{ "p1":"Custom Attribute1", "p2":"Custom Attribute2" } },{ "id":123, "text":"Microsoft Office" },{ "id":124, "text":"Games", "checked":true }] },{ "id":13, "text":"index.html" },{ "id":14, "text":"about.html" },{ "id":15, "text":"welcome.html" }] }]
第一次看了之后,由於沒有思路就給放棄了,就采取了Tree中的老大ZTree,可以問題接踵而至,它與前台的EasyUi有時會發生沖突,沒辦法最后還是只能采取EasyUi中Tree,仔細分析一下,貌似可以采用算法中的遞歸來實現,於是乎小編就有了以下的解決思路。
1.先創建一個符合EasyUi中樹形格式的類
/* 樹的節點類 id:節點id,對載入遠程數據很重要。 text:顯示在節點的文本。 state:節點狀態,'open' or 'closed',默認為'open'。當設置為'closed'時,擁有子節點的節點將會從遠程站點載入它們。 checked:表明節點是否被選擇。 children:子節點,必須用數組定義。 */ public class TreeNode { public string id { get; set; } //節點的id值 public string text { get; set; } //節點顯示的名稱 public string state { get; set; }//節點的狀態
// 請在整個樹轉換成jsonString時,將字符串Checked換成checked,否則easyui不認
public bool Checked { get; set; } //注意:轉成JsonTreeString時,將"Checked"替換成"checked",否則選中效果出不來的
public List<TreeNode> children { get; set; } //集合屬性,可以保存子節點 }
2.把從后台查出來的對象,轉換成為EasyUi中格式
#region 2.0 將當前組織 對象 轉成 樹節點對象 +TreeNode ToNode() /// <summary> /// 將當前組織 對象 轉成 樹節點對象 /// </summary> /// <returns></returns> public TreeNode ToNode() { TreeNode node = new TreeNode() { id = this.pid, text = this.OrganizationName, state = "open", Checked = false, children = new List<TreeNode>() }; return node; } #endregion
3.第三步通過遞歸轉換好的樹形節點,來找到自己的子節點,然后放到自己默認的屬性中
#region 2.0 將 組織集合 轉成 樹節點集合 +List<MODEL.EasyUIModel.TreeNode> ToTreeNodes(List<Ou_Permission> listPer) /// <summary> /// 將 組織集合 轉成 樹節點集合 /// </summary> /// <param name="listPer"></param> /// <returns></returns> public static List<TreeNode> ToTreeNodes(List<Organization> listPer) { List<TreeNode> listNodes = new List<TreeNode>(); //生成 樹節點時,根據 pid=0的根節點 來生成 LoadTreeNode(listPer, listNodes, "0");
//if (listCurrentPermissions.Count > 0)
//listNodes[0].Checked = false;
SetFathersUnchecked(listNodes, argPId);
return listNodes; } #endregion #region 3.0 遞歸組織集合 創建 樹節點集合 /// <summary> /// 遞歸組織集合 創建 樹節點集合 /// </summary> /// <param name="listPer">組織集合</param> /// <param name="listNodes">節點集合</param> /// <param name="pid">節點父id</param> public static void LoadTreeNode(List<Organization> listPer, List<TreeNode> listNodes, string pid) { foreach (var permission in listPer) { //如果組織父id=參數 if (permission.pParent == pid) { //將 組織轉成 樹節點 TreeNode node = permission.ToNode(); //將節點 加入到 樹節點集合 listNodes.Add(node); //遞歸 為這個新創建的 樹節點找 子節點 LoadTreeNode(listPer, node.children, node.id); } } } #endregion
public static void SetFathersUnchecked(List<TreeNode> listNodes, string pid)
{
//葉子節點,則取消父節點的勾選狀態,讓其變成不確定狀態 (否則會自動勾選父下的所有節點而顯示不正確)
foreach (var node in listNodes)
{
if (node.children.Count > 0)
{
SetFathersUnchecked(node.children, node.id);
if (node.children.Exists(c => c.Checked)//如果節點A下有勾選的子節點,則節點A取消勾選(界面上會自動變成不確定狀態)
|| node.children.TrueForAll(c => !c.Checked))//都未勾選,則父取消勾選
node.Checked = false;
}
else
{
//葉子節點
}
}
}
public static class Extensions
{
/// <summary>
/// 轉換成Json串,供界面easyui使用
/// </summary>
public static string ToJson(this List<TreeNode> list)
{
string res = DataHelper.Obj2Json(list);
res = res.Replace("\"Checked\"", "\"checked\"");
return res;
}
}
通過以上操作最終就返回了類似樹形結構的集合,只要在轉換為Json串就OK了,當然也可以采用strbuilder的形式來拼接,但是那樣操作起來有點太麻煩了,所以采取了遞歸的形式。