ExtAspNet应用技巧(二十二) - Ext4JSLint之JSON文件创建树控件

原创|其它|编辑:郝浩|2009-09-24 09:38:14.000|阅读 1188 次

概述:Ext4JSLint是使用ExtAspNet来展示JSLint-Toolkit检查结果的开源项目。 JSLint-Toolkit是一个使用Rhino和JSLint的开源项目,可以对一个文件夹中的所有JavaScript进行语法检查,并显示友好的检查结果。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

引子

Ext4JSLint是使用ExtAspNet来展示JSLint-Toolkit检查结果的开源项目。
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.        else
13.        {
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.        else
34.        {
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.        else
013.        {
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.        else
029.        {
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.            else
055.            {
056.                if (criticalErrorCount == 0)
057.                {
058.                    style = "color:#FF9900;";
059.                }
060.                else
061.                {
062.                    style = "color:#FF0000;";
063.                }
064.            }
065.        }
066.        else
067.        {
068.            if (criticalErrorCount != 0)
069.            {
070.                style = "color:#FF0000;";
071.            }
072.            else
073.            {
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.        else
084.        {
085.            node.Leaf = true;
086.            if (showAllErrors)
087.            {
088.                if (errorCount != 0)
089.                {
090.                    node.EnablePostBack = true;
091.                    node.CommandName = currentPath;
092.                }
093.            }
094.            else
095.            {
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@evget.com

文章转载自:博客园

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP