Jumony入门(二)初识选择器
首先介绍一下Jumony是什么,Jumony是一个.NET的开源项目,项目主页位于:http://jumony.codeplex.com/,采用LGPL协议发布。
Jumony试图提供在传统Web开发模型中许多难以解决问题的解决方案。一言蔽之,Jumony的一切基础建立在服务器端的HTML DOM之上。在服务器端将HTML(文件或动态网页技术的输出)按照客户端浏览器的处理方式解析为HTML DOM。操纵和处理HTML DOM,就像我们在客户端用JavaScript干的那些事情一样,不同的是,Jumony可以使你依托强大的.NET Framework,来解决以前用脚本和服务器端技术都难以解决的事情。
系列目录:
这是系列文章的第二篇,这个系列尝试一步步从一些最简单的例子开始了解怎么玩转Jumony。建议先从第一篇开始学习搭建Jumony环境,在本文的开始的时候,假设大家已经搭建好了Jumony的运行环境。
首先我们来看一个页面:
这个页面的源代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Ranks</title>
<style>
table
{
font-size: 12px;
}
.ranks th
{
height: 30px;
font-size: 15px;
font-family: Arial;
}
.ranks td, .ranks th
{
border-top: solid 1px;
}
.ranks .name
{
font-weight: bold;
}
.ranks table td
{
border: 0px;
}
</style>
</head>
<body>
<table cellpadding="5" cellspacing="0" class="ranks">
<tr>
<td colspan="2" class="top">
<table cellpadding="3" border="0">
<tr>
<td rowspan="3"><img src="http://pic.cnblogs.com/avatar/a14218.jpg" width="50" height="50" /></td>
<td class="name">Jumony</td>
</tr>
<tr>
<td>得票数: <span style="color: red;">100</span></td>
</tr>
<tr>
<td>主页地址: <a href="http://jumony.codeplex.com/">http://jumony.codeplex.com/</a></td>
</tr>
</table>
</td>
</tr>
<tr>
<th>
№ 2
</th>
<td><span class="name" >Jumony</span>( <span style="color: red;">100</span> ) <a href="http://jumony.codeplex.com/">http://jumony.codeplex.com/</a></td>
</tr>
<tr>
<th>
№ 3
</th>
<td><span class="name" >Jumony</span>( <span style="color: red;">100</span> ) <a href="http://jumony.codeplex.com/">http://jumony.codeplex.com/</a></td>
</tr>
</table>
</body>
</html>
请先将份源代码保存为一个叫做ranks.htm的文件,然后我们开始对这个页面干点儿坏事。
这种页面,就是一种在传统的技术下,怎么也不好处理的页面,第一名的呈现方式与后面的呈现方式完全不同。即使用模版引擎,这种模版改起来怕也是件烦心事儿。
但强大CSS的选择器可以完全的抹平这些区别,使得我们的逻辑变得非常简单。
当然,首先,我们要建立一个这个页面的处理程序,也就是ranks.htm.ashx文件。然后添加using和继承基类,完成后的样子像这样:
那么首先,我们要选择到class为ranks的那个table,再选择其每一行,选择器像是这样的:".ranks > tr"。
中间的>符号表示只选择.ranks的直接子集中的tr,因为在第一名的行中,HTML里面又被嵌了一个table来做绑定,里面也有一些tr元素。所以我们使用>选择符来避免选择到这些:
关于选择器的语法,是完全遵循CSS Selector 3的标准的(部分实现)。如有不清楚的地方可以移步W3C的网站:http://www.w3.org/TR/2009/PR-css3-selectors-20091215/
另外需要注意的是这里我们是直接用Find方法的,而不是Document.Find,嗯,这是JumonyHandler提供的一个便利,对于Document的Find操作实在是太常用了,所以,Handler上定义了一个Find方法来对Document进行查找。当然,这和Document.Find是完全一样的效果。
然后我们编造一些数据,例如:
接下来是将两个列表绑定在一起,Ivony.Fluent里面提供了一个方法:BindTo,这个方法可以方便的进行两个列表的绑定,使用方法像是这样:
这里我使用的是lambda表达式,如果你喜欢也可以写成一个额外的方法,当然,在这个例子中,由于上面的数据类型我用的是匿名类型,所以这里没有办法拆出另一个方法出来,那么,我继续用lambda来示范。
获取了每一个绑定的元素后,我们需要进一步考察每一个项(即Name、Votes和Url)要绑定的位置。只要是有规律的界面,那么其HTML就一定是有规律的,其实这个规律并不难找:
Name位于class="name"的元素中,而Votes则总是在一个style="color: red"的span里面,至于url,则总是在<a>那里,因为这是一个链接。当然,这个页面也可以说是事先设计好的,因为这里才第二篇,我们只考虑一些简单的示范,在后面,我们再来看在代码中的筛选逻辑能够做到怎样的智能。那么我们可以简单的写出选择器:
注意这里的element直接就有Find方法,事实上Find方法并不是Document的专利,在Jumony中,只要是一个容器(IHtmlContainer),就可以Find,这实在非常便利。
OK,现在数据就已经全部绑定到页面了,打开页面来看看效果。
很完美不是么?看看HTML源代码:
怎么样,有没有一种在服务器端用jQuery的感觉?
这里有几个问题需要注意一下:
- CSS选择器的关系选择符,如">"或是"+"这些,在标准中两边是不必留有空白的,即可以写成".ranks>tr"。但Jumony不允许,是刻意如此,并非技术所限不能支持。因为Jumony认为强制性的留白可以提高这些选择符的可读性。
- 现有的版本中,不支持CSS Selector 3标准中的:not伪类和,选择符,其余的全部支持。jQuery的私有伪类则全部不支持。
- 如果你觉得linkContainer.SetAttribute( "href" ).Value( dataItem.Url )这种写法很恶心,那么不必担心。下个版本就可以这样写了:
linkContainer.SetAttribute( "href" ,dataItem.Url )
还可以这样:linkContainer.href = dataItem.Url