在混合開發框架模式中,有時候我們在處理樹形節點的時候,需要很多關聯的處理,可能需要結合用戶配置信息,屬性字典,以及表的欄位分類等信息來展示一個結構樹,那麼在處理的時候就可能會頻繁的對這些介面API進行調用,而如果我們使用Web API一次性的獲取樹形節點信息,然後統一載入的話,性能會提升很多,本篇隨... ...
在混合開發框架模式中,有時候我們在處理樹形節點的時候,需要很多關聯的處理,可能需要結合用戶配置信息,屬性字典,以及表的欄位分類等信息來展示一個結構樹,那麼在處理的時候就可能會頻繁的對這些介面API進行調用,而如果我們使用Web API一次性的獲取樹形節點信息,然後統一載入的話,性能會提升很多,本篇隨筆介紹通過封裝一個總的樹形結構列表數據返回的Web API,從而在Winform客戶端一次性展示的方式,實現性能的優化處理。
1、樹形結構展示效果
如下麵的CRM客戶關係管理系統中,我們需要展示很多客戶相關的樹形節點,以方便快捷查詢相關類型的客戶信息。
那麼這個樹列表就需要結合很多屬性來處理了,包括了客戶的欄位信息,客戶配置顯示信息,每個欄位類型的對應的字典信息,如客戶狀態、客戶類型等等。
因此如果在客戶端整合邏輯,那麼需要對幾個不同的處理介面進行調用並處理,這種解析起來比較慢,而且也會導致處理效率問題。
一般情況下,我們雲端的伺服器性能會比客戶端的性能更好一些,這些對資料庫處理的邏輯封裝在Web API的後盾會更加方便,也就是瘦客戶端的方式更有效率了。
2、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端的控制器方法如下所示。
最後具體在客戶端界面綁定顯示數據的邏輯如下所示。
/// <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多行代碼,具體就不再一一介紹了,主要就是對各個介面的處理,獲取數據並組裝起來。
這種在伺服器端對主要邏輯進行封裝,簡化客戶端的處理邏輯,是我們推薦的方式,可以極大的提高界面響應效率,減少不必要的網路延遲損耗,從而提高用戶的體驗效果,對於具有較高運算速度的伺服器,更是物盡其用。