符合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的形式來拼接,但是那樣操作起來有點太麻煩了,所以采取了遞歸的形式。
