引子
Ext4JSLint是使用ExtAspNet来展示JSLint-Toolkit检查结果的开源项目。
JSLint-Toolkit是一个使用Rhino和JSLint的开源项目,可以对一个文件夹中的所有JavaScript进行语法检查,并显示友好的检查结果。
下面是JSLint-Toolkit为JavaScript生成的错误列表:
[ [3, 39, 20, "Expected a number and instead saw '''.", "/Expected '{' and instead saw '.+'\\./,"], [3, 39, 21, "Expected '}' and instead saw ' '.", "/Expected '{' and instead saw '.+'\\./,"], [3, 68, 18, "Be careful when making functions within a loop. Consider putting the function in a closure.", "})();"] ]
这是一个类似二位数组的结构,每个数组有4列,分别表示错误级别,第几行,第几列,错误信息,错误代码。
界面截图
使用SyntaxHighlighter显示JavaScript源代码
首先看下右侧IFrame中,如何使用SyntaxHighlighter来显示JavaScript源代码。
<html> <head> <title>Untitled Page</title> <link href="js/syntax/styles/shCore.css" rel="stylesheet" type="text/css" /> <link href="js/syntax/styles/shThemeDefault.css" rel="stylesheet" type="text/css" /> <style type="text/css""> html, body { font-size: 12px; margin: 0px; padding: 0px; } .syntaxhighlighter { margin: 0 !important; } </style> <script src="js/jquery-1.3.2.min.js" type="text/javascript"></script> <script src="js/syntax/scripts/shCore.js" type="text/javascript"></script> <script src="js/syntax/scripts/shBrushJScript.js" type="text/javascript"></script> <script type="text/javascript"> // TODO </script> </head> <body> </body> </html>
我们引入了jQuery,来完成AJAX操作以及页面的平滑滚动,来看下JavaScript代码:
SyntaxHighlighter.config.clipboardSwf = 'js/syntax/scripts/clipboard.swf'; window.highlight = function(number) { $(".line, highlighted").removeClass("highlighted"); var top = $(".line:eq(" + (number - 1) + ")").addClass("highlighted").offset().top - 150; $("html, body").animate({ scrollTop: top }, 500); }; window.loadJS = function(url, fn) { $.get(url, function(data) { data = data.replace(/</g, "<").replace(/>/g, ">").replace(/\/r\/n/g, "<br />"); $("body").html(""); $("<pre class=\"brush: js\">" + data + "</pre>").appendTo("body"); SyntaxHighlighter.highlight(); if (fn) { fn(); } }, "text"); };
其中window.loadJS用来读取一个url的内容(这里是JavaScript文件),并使用SyntaxHighlighter高亮显示在页面。
window.highlight用来高亮显示某一行源代码,同时这里使用jQuery的animate函数来完成页面的平滑滚动。
由于这个页面是嵌入在父页面中的,所以接下来你会看到如何在父页面中操作这两个JavaScript函数。
父页面中的JavaScript定义
<script type="text/javascript"> function onReady() { selectGridRow(); } function selectGridRow() { var grid = Ext.getCmp("<%= Grid1.ClientID %>"); grid.getSelectionModel().on("rowselect", function(sm, rowIndex, record) { getMainWindow().highlight(parseInt(record.json[0].replace(/<.*?>/g, ""))); }); } function getMainWindow() { return Ext.query("iframe[name=main]")[0].contentWindow; } </script>
其中getMainWindow用来获取IFrame的window实例。
而selectGridRow会在页面加载完毕后立即执行,用来在选中Grid的某一行时高亮显示右侧IFrame中的对应行的源代码(这里用到了上面提到的highlight函数)。
点击树节点的事件处理
还记得在上一章中,我们为Tree注册了OnNodeCommand="Tree1_NodeCommand",下面来看下此函数:
protected void Tree1_NodeCommand(object sender, ExtAspNet.TreeCommandEventArgs e) { string fileName = e.CommandName.Replace("/", "_"); if (ViewState["CurrentFileName"] != null && ViewState["CurrentFileName"].ToString() == fileName) { return; } ViewState["CurrentFileName"] = fileName; string errorstr = GetFileContent(String.Format("~/data/errors/{0}.json", fileName)); JSONArray ja = new JSONArray(errorstr); DataTable table = new DataTable(); table.Columns.Add("level", typeof(Int32)); table.Columns.Add("line", typeof(Int32)); table.Columns.Add("character", typeof(Int32)); table.Columns.Add("reason", typeof(String)); table.Columns.Add("evidence", typeof(String)); foreach (JSONArray error in ja.getArrayList()) { DataRow row = table.NewRow(); table.Rows.Add(row); row[0] = Convert.ToInt32(error[0]); row[1] = Convert.ToInt32(error[1]); row[2] = Convert.ToInt32(error[2]); row[3] = error[3].ToString(); row[4] = error[4].ToString(); } Grid1.DataSource = table; Grid1.DataBind(); string showSourceScript = "(function(){getMainWindow().loadJS('data/source/" + fileName + "');}).defer(100);"; ExtAspNet.PageContext.RegisterStartupScript(showSourceScript); }
这里面有两个应用技巧:
- 点击树节点时,需要在后台获取此节点的相关信息怎么办?通过TreeNode的CommandName或者CommandArgument来传递。
- 点击树节点时,除了要绑定Grid1外,还需要加载IFrame中JavaScript的内容,这通过ExtAspNet.PageContext.RegisterStartupScript来执行一段脚本。
注:ExtAspNet.PageContext.RegisterStartupScript是一个常用的函数,以后你会经常遇到。
在注册的脚本中,我们使用defer(100)来让这段脚本延迟一段执行,这是为了防止浏览器卡(因为同时绑定Grid和发起AJAX可能很耗资源)。
根据错误级别为Grid每一项添加文字颜色
对于非常严重的错误,需要标示文字颜色为红色,而对于不要严重的错误只需文字颜色为淡黄色就行了。
为了实现这一效果,我们有两种不同的方法都可以达到相同的目的。
1. 方法一,在Grid的RowDataBound事件做文章(这也是Asp.net的GridView控件常用的技巧)
protected void Grid1_RowDataBound(object sender, ExtAspNet.GridRowEventArgs e) { // DataItem是行的数据源, // 如果数据源是DataTable/DataView/DataSet,则e.DataItem是DataRow // 如果数据源是List<MyClass>,则e.DataItem是MyClass // e.Values 是实际赋予此行每列的值,可以修改 DataRow row = e.DataItem as DataRow; if (row != null) { int level = Convert.ToInt32(row["level"]); string style = String.Empty; if (level == 1) { style = "color:#FF0000;"; } else { style = "color:#FF9900;"; } for (int i = 0; i < e.Values.Length; i++) { e.Values[i] = String.Format("<span style=\"{0}\">{1}</span>", style, e.Values[i]); } } }
2. 方法二,在Grid的PreRowDataBound事件做文章(这是ExtAspNet特有的事件)
需要特别注意的是,这里改变的是一列的属性(请细细品味是列的属性,不是某一行的属性)。
protected void Grid1_PreRowDataBound(object sender, ExtAspNet.GridPreRowEventArgs e) { DataRow row = e.DataItem as DataRow; if (row != null) { int level = Convert.ToInt32(row["level"]); string style = String.Empty; if (level == 1) { style = "color:#FF0000;"; } else { style = "color:#FF9900;"; } foreach (ExtAspNet.GridColumn column in Grid1.Columns) { ExtAspNet.BoundField field = column as ExtAspNet.BoundField; field.DataFormatString = "<span style=\"" + style + "\">{0}</span>"; } } }
关于Ext4JSLint的内容就先介绍到这,下一章我们会接着介绍AppBox。
下载全部源代码