原創|其它|編輯:郝浩|2009-09-24 09:38:14.000|閱讀 1197 次
概述:Ext4JSLint是使用ExtAspNet來展示JSLint-Toolkit檢查結果的開源項目。 JSLint-Toolkit是一個使用Rhino和JSLint的開源項目,可以對一個文件夾中的所有JavaScript進行語法檢查,并顯示友好的檢查結果。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
引子
Ext4JSLint是使用來展示JSLint-Toolkit檢查結果的開源項目。
是一個使用Rhino和JSLint的開源項目,可以對一個文件夾中的所有JavaScript進行語法檢查,并顯示友好的檢查結果。
下面是JSLint-Toolkit生成的檢查結果:
01.[{ 02. "name": "source", 03. "type": "folder", 04. "kids": [ 05. { 06. "name": "config.js", 07. "type": "file", 08. "errors": [0, 0, 0] 09. }, 10. { 11. "name": "lint.js", 12. "type": "file", 13. "errors": [3, 0, 3] 14. }, 15. { 16. "name": "main.js", 17. "type": "file", 18. "errors": [0, 0, 0] 19. }, 20. { 21. "name": "util.js", 22. "type": "file", 23. "errors": [0, 0, 0] 24. } 25. ], 26. "basePath": "scripts/source", 27. "fileCount": 4, 28. "errors": [3, 0, 3] 29.}, 30.{ 31. "name": "jquery-1.3.2.js", 32. "type": "file", 33. "basePath": "scripts/jquery-1.3.2.js", 34. "errors": [51, 43, 8] 35.}]
這樣一個JSON字符串其實描述了一個如下的文件結構:
+scripts/source
-config.js
-lint.js
-main.js
-util.js
-scripts/jquery-1.3.2.js
特別注意的是,根節點多了一個屬性basePath用來表示根路徑。
errors表示此JavaScript文件中的錯誤數(這是一個數組,第一個表示總數,第二個表示嚴重錯誤的個數)。
頁面效果:
ASPX標簽定義
1.<ext:Tree runat="server" ID="Tree1" ShowBorder="false" ShowHeader="false" AutoScroll="true"2. EnableArrows="true" OnNodeCommand="Tree1_NodeCommand"> 3.</ext:Tree>
標簽定義非常簡單,因為所有的邏輯都在后臺實現了。
同時定義了點擊樹節點的事件處理OnNodeCommand="Tree1_NodeCommand",因為我們要在點擊樹節點時更新中間的Grid,也即是當前JavaScript的錯誤列表。
樹與遞歸
只要有樹的地方就少不了遞歸函數,因此這段代碼對于我們理解遞歸也很有幫助。
首先看看頁面初始化代碼:
01.protected void Page_Load(object sender, EventArgs e) 02.{ 03. if (!IsPostBack) 04. { 05. LoadData(true); 06. } 07.} 08.#region LoadData 09.private void LoadData(bool showAllErrors) 10.{ 11. btnExpandAll.OnClientClick = Tree1.GetExpandAllNodesReference(); 12. btnCollapseAll.OnClientClick = Tree1.GetCollapseAllNodesReference(); 13. string treestr = GetFileContent("~/data/json/tree.json"); 14. List<string> treePathList = new List<string>(); 15. ResolveMenuTree(new JSONArray(treestr), treePathList, showAllErrors, Tree1.Nodes); 16.} 17.private string GetFileContent(string path) 18.{ 19. string treestr = String.Empty; 20. using (StreamReader sr = new StreamReader(Server.MapPath(path))) 21. { 22. treestr = sr.ReadToEnd(); 23. } 24. return treestr; 25.} 26.private void ResolveMenuTree(JSONArray ja, List<string> treePathList, bool showAllErrors, ExtAspNet.TreeNodeCollection nodes) 27.{ 28. // TODO 遞歸生成樹 29.} 30.private string GetTreePath(List<string> treePath) 31.{ 32. string path = String.Empty; 33. foreach (string node in treePath) 34. { 35. path += node + "/"; 36. } 37. return path.TrimEnd('/'); 38.}
我們通過Nii.JSON這個開源類庫(已經包含在ExtAspNet中),來將JSON字符串轉換為JSONArray對象,以便在遞歸中使用:
1.JSONArray ja = new JSONArray(treestr);
遞歸生成樹
為了讓大家看清問題的本質,我首先放出一個簡單的遞歸,只完成基本功能:
01.private void ResolveMenuTree2(JSONArray ja, List<string> treePathList, bool showAllErrors, ExtAspNet.TreeNodeCollection nodes) 02.{ 03. for (int i = 0; i < ja.Count; i++) 04. { 05. JSONObject kid = ja[i] as JSONObject; 06. string name = kid.getString("name"); 07. // 當前路徑,如果basePath存在說明是根目錄 08. if (kid.has("basePath")) 09. { 10. treePathList.Add(kid.getString("basePath")); 11. } 12. else13. { 14. treePathList.Add(name); 15. } 16. string currentPath = GetTreePath(treePathList); 17. string type = kid.getString("type"); 18. // 如果文件夾中沒有文件,則不添加此文件夾 19. if (type == "folder" && kid.getInt("fileCount") == 0) 20. { 21. treePathList.RemoveAt(treePathList.Count - 1); 22. continue; 23. } 24. ExtAspNet.TreeNode node = new ExtAspNet.TreeNode(); 25. nodes.Add(node); 26. node.Text = name; 27. node.Text = String.Format("<span qtip=\"{0}\">{1}</span>", currentPath, node.Text); 28. if (type == "folder") 29. { 30. node.SingleClickExpand = true; 31. ResolveMenuTree2(kid.getJSONArray("kids"), treePathList, showAllErrors, node.Nodes); 32. } 33. else34. { 35. node.Leaf = true; 36. } 37. treePathList.RemoveAt(treePathList.Count - 1); 38. } 39.}
在這段代碼中,我們通過treePathList來記錄當前節點的路徑,這也是一個關鍵點。
此時生成的頁面截圖:
完整的代碼(根據錯誤設置節點顏色,同時為有錯誤的節點可回發):
001.private void ResolveMenuTree(JSONArray ja, List<string> treePathList, bool showAllErrors, ExtAspNet.TreeNodeCollection nodes) 002.{ 003. for (int i = 0; i < ja.Count; i++) 004. { 005. JSONObject kid = ja[i] as JSONObject; 006. string name = kid.getString("name"); 007. // 當前路徑,如果basePath存在說明是根目錄 008. if (kid.has("basePath")) 009. { 010. treePathList.Add(kid.getString("basePath")); 011. } 012. else013. { 014. treePathList.Add(name); 015. } 016. string currentPath = GetTreePath(treePathList); 017. // 獲取JSLint錯誤數 018. JSONArray errors = kid.getJSONArray("errors"); 019. int errorCount = errors.getInt(0); 020. int criticalErrorCount = errors.getInt(1); 021. if (showAllErrors) 022. { 023. if (errorCount > 0) 024. { 025. name += String.Format(" ({0})", errorCount); 026. } 027. } 028. else029. { 030. if (criticalErrorCount > 0) 031. { 032. name += String.Format(" ({0})", criticalErrorCount); 033. } 034. } 035. string type = kid.getString("type"); 036. // 如果文件夾中沒有文件,則不添加此文件夾 037. if (type == "folder" && kid.getInt("fileCount") == 0) 038. { 039. treePathList.RemoveAt(treePathList.Count - 1); 040. continue; 041. } 042. ExtAspNet.TreeNode node = new ExtAspNet.TreeNode(); 043. nodes.Add(node); 044. node.Text = name; 045. //node.ToolTip = currentPath; 046. // 節點的顯示顏色 047. string style = ""; 048. if (showAllErrors) 049. { 050. if (errorCount == 0) 051. { 052. style = "color:green;"; 053. } 054. else055. { 056. if (criticalErrorCount == 0) 057. { 058. style = "color:#FF9900;"; 059. } 060. else061. { 062. style = "color:#FF0000;"; 063. } 064. } 065. } 066. else067. { 068. if (criticalErrorCount != 0) 069. { 070. style = "color:#FF0000;"; 071. } 072. else073. { 074. style = "color:green;"; 075. } 076. } 077. node.Text = String.Format("<span qtip=\"{2}\" style=\"{0}\">{1}</span>", style, node.Text, currentPath); 078. if (type == "folder") 079. { 080. node.SingleClickExpand = true; 081. ResolveMenuTree(kid.getJSONArray("kids"), treePathList, showAllErrors, node.Nodes); 082. } 083. else084. { 085. node.Leaf = true; 086. if (showAllErrors) 087. { 088. if (errorCount != 0) 089. { 090. node.EnablePostBack = true; 091. node.CommandName = currentPath; 092. } 093. } 094. else095. { 096. if (criticalErrorCount != 0) 097. { 098. node.EnablePostBack = true; 099. node.CommandName = currentPath; 100. } 101. } 102. } 103. treePathList.RemoveAt(treePathList.Count - 1); 104. } 105.}
下一章將講述如何點擊左側樹節點時更新中間的Grid控件,并加載右側的IFrame(即JavaScript文件的內容)。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@ke049m.cn
文章轉載自:博客園