在混合開發框架模式中,有時候咱們在處理樹形節點的時候,須要不少關聯的處理,可能須要結合用戶配置信息,屬性字典,以及表的字段分類等信息來展現一個結構樹,那麼在處理的時候就可能會頻繁的對這些接口API進行調用,而若是咱們使用Web API一次性的獲取樹形節點信息,而後統一加載的話,性能會提高不少,本篇隨筆介紹經過封裝一個總的樹形結構列表數據返回的Web API,從而在Winform客戶端一次性展現的方式,實現性能的優化處理。node
以下面的CRM客戶關係管理系統中,咱們須要展現不少客戶相關的樹形節點,以方便快捷查詢相關類型的客戶信息。數據庫
那麼這個樹列表就須要結合不少屬性來處理了,包括了客戶的字段信息,客戶配置顯示信息,每一個字段類型的對應的字典信息,如客戶狀態、客戶類型等等。後端
所以若是在客戶端整合邏輯,那麼須要對幾個不一樣的處理接口進行調用並處理,這種解析起來比較慢,並且也會致使處理效率問題。服務器
通常狀況下,咱們雲端的服務器性能會比客戶端的性能更好一些,這些對數據庫處理的邏輯封裝在Web API的後盾會更加方便,也就是瘦客戶端的方式更有效率了。網絡
例如咱們定義一個如下的接口來獲取數據。框架
/// <summary> /// 獲取客戶樹形類別的數據 /// </summary> /// <param name="userId">當前用戶ID</param> /// <param name="companyId">所屬公司ID</param> /// <param name="dataFilter">數據過濾條件</param> /// <param name="shareUserCondition">分配用戶ID條件</param> /// <returns></returns> List<TreeNodeInfo> GetCustomerTree(string userId, string companyId, string dataFilter, string shareUserCondition);
其中TreeNodeInfo對象是咱們本身定義的一個對象,用來承載具備層級信息的列表信息。函數
具體這個類的代碼以下所示。性能
/// <summary> /// 用來承載TreeNode的信息 /// </summary> [Serializable] [DataContract] public class TreeNodeInfo { /// <summary> /// 子對象集合 /// </summary> [DataMember] public List<TreeNodeInfo> Nodes { get; set; } /// <summary> /// 節點名稱 /// </summary> [DataMember] public string Text { get; set; } /// <summary> /// 節點標籤 /// </summary> [DataMember] public string Tag { get; set; } /// <summary> /// 圖標序號 /// </summary> [DataMember] public int IconIndex { get; set; } /// <summary> /// 是否展開 /// </summary> [DataMember] public bool IsExpanded { get; set; } /// <summary> /// 前景色 /// </summary> [DataMember] public string ForeColor { get; set; } /// <summary> /// 默認構造函數 /// </summary> public TreeNodeInfo() { this.Nodes = new List<TreeNodeInfo>(); } /// <summary> /// 參數構造函數 /// </summary> /// <param name="text">節點名稱</param> /// <param name="iconIndex">圖標序號</param> /// <param name="tag">節點標籤</param> public TreeNodeInfo(string text, int iconIndex, string tag = "") : this() { this.Text = text; this.IconIndex = iconIndex; this.Tag = tag; } }
Web API端的控制器方法以下所示。優化
最後具體在客戶端界面綁定顯示數據的邏輯以下所示。this
/// <summary> /// 使用Json對象建立列表樹 /// </summary> private void InitTree() { //清空節點信息 this.treeView1.Nodes.Clear(); //經過Web API方式獲取樹對象列表結構 var list = CallerFactory<ICustomerService>.Instance.GetCustomerTree(LoginUserInfo.ID, this.SelectedCompanyID, this.DataFilterCondition, this.ShareUserCondition); if (list != null && list.Count > 0) { //遍歷每一個節點,生成對應的TreeView對象節點 foreach (var node in list) { //構建TreeView對象節點信息 TreeNode parentNode = new TreeNode(node.Text, node.IconIndex, node.IconIndex); parentNode.Tag = node.Tag; if (!string.IsNullOrEmpty(node.ForeColor)) { //若是節點顏色有值,則修改前景色 parentNode.ForeColor = ColorTranslator.FromHtml(node.ForeColor); } //遞歸處理樹形列表 InitTreeNode(node.Nodes, parentNode); if (parentNode.Text != "標記顏色") { parentNode.Expand();//選擇性的展開部分一級節點 } //把根節點加入到樹對象裏面顯示 this.treeView1.Nodes.Add(parentNode); } } } /// <summary> /// 遞歸處理樹形列表 /// </summary> /// <param name="nodes">樹節點信息對象</param> /// <param name="pNode">TreeView根節點</param> private void InitTreeNode(List<TreeNodeInfo> nodes, TreeNode pNode) { foreach (TreeNodeInfo node in nodes) { TreeNode subNode = new TreeNode(node.Text, node.IconIndex, node.IconIndex); subNode.Tag = node.Tag; if (!string.IsNullOrEmpty(node.ForeColor)) { //若是節點顏色有值,則修改前景色 subNode.ForeColor = ColorTranslator.FromHtml(node.ForeColor); } //遞歸調用 InitTreeNode(node.Nodes, subNode); pNode.Nodes.Add(subNode); } }
這裏基本不會涉及不少邏輯,咱們只須要對樹形節點的結構進行遍歷展現便可。
其實後端已經給咱們處理好不少數據了,包括對節點構建、數據字典的處理,以及每一個條件的數量處理都合併一塊兒,它的邏輯仍是不少的。
這個部分的邏輯因爲代碼量比較大,咱們能夠簡化抽取出來一個輔助類處理,這樣在須要的地方直接調用輔助類進行處理就能夠了。
抽取輔助類後,對處理邏輯的調用簡單了不少。
CustomerHelper helper = new CustomerHelper(); var result = helper.GetCustomerTree(userId, companyId, dataFilter, shareUserCondition);
這部分有300多行代碼,具體就再也不一一介紹了,主要就是對各個接口的處理,獲取數據並組裝起來。
這種在服務器端對主要邏輯進行封裝,簡化客戶端的處理邏輯,是咱們推薦的方式,能夠極大的提升界面響應效率,減小沒必要要的網絡延遲損耗,從而提升用戶的體驗效果,對於具備較高運算速度的服務器,更是物盡其用。