引子
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=\" 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。
下载全部源代码