Tapestry学习十五:关于组件(十)GRID组件

Grid 组件

 

以前, 我们用LOOP组件去展示集合中的名人.它也并不困难,而且在许多情况下,他完全可以解决你的要求。 但是, 随着集合中名人的增多,问题也就随之而来.

我们不想一下子把所有的名人都显示在一个页面上,我们需要一个分页的机制,同时可对姓名和职业等进行排序。我们可以增加很多代码和控制去实现我们想要的效果,但表的分页和排序的列是用户界面的非常整体的一部分,并且每一次展现它都不是很有效率。

还好有Grid组件,把showall.tml中的关于loop的代码:

<table width="100%">

<tr t:type="loop" t:source="allCelebrities"

t:value="celebrity">

<td>

<a href="#" t:type="PageLink" t:page="Details"

t:context="celebrity.id">

${celebrity.lastName}

</a>

</td>

<td>${celebrity.firstName}</td>

<td>

<t:output t:format="dateFormat"

t:value="celebrity.dateOfBirth"/>

</td>

<td>${celebrity.occupation}</td>

</tr>

</table>

 

替换成:

<t:grid t:source="allCelebrities"/>

 

运行,showall的页面去看一看:

 

只用一行代码就展现除了另我们印象深刻的效果是不是(说实话,代码是很少,但是效果咋地,可以说很丑,不及EXT一半的强大)?不仅我们所有的名人都显示在一个整齐的表中,而且点击表的列还可以排序。注意看职业列,因为enum的原因在前面显示的全是大写的字母那个现象不见了,现在是首字母大写的。

在这里我们看到了Tapestry强大的另一面,Grid组件唯一需要的参数就是source,这个参数和Loop组件的source参数一样,通过这个参数,Grid组件收到很多同一类型的对象,它取出集合中的第一个对象并查找它的属性,grid试着为每一个属性都创建个列,把属性的名字变列名,并做出一些额外的调整,比如在我们列子中的职业列。

一切都很让你兴奋,但是这个table还有很多不足:

1、              所有的名人都在这个页面上,并没有出现我们想要的分页,这是因为,默认的分页条目是25条,多于我们集合中的名人数。

2、              lasename列上没有超链接去查看详细信息。

3、              ID属性没有必要显示出来。

4、              列的排序是不合理的,lastname应该在firstname之前,然后是date of brith

         

          注:Grid默认的列的排序是根据展示的实体类当中的getter方法的顺序去排序的。

还有其他的问题我们要去当心的,但是现在我们先解决这是个问题。

 

打造Gird

 

首先我们来改变每页显示的记录,在要在grid组件中加个属性就可以了:

<t:grid t:source="allCelebrities" rowsPerPage=” 5” />

 

效果:

 

说一下:作者用的版本默认分页的链接在下面,最近版本的默认分页链接在上面。Tapestry这狗日的就这么善变。这时需要加个pagerposition属性:"top", "bottom", "both" or "none".知道是什么意思了吧。等会儿可能还会说要更个性化的。

 

下面我们将要为lastname列增加超链接,去显示详细页面了,这时就必要知道每一行是那一个名人,这就需要grid增加一个属性:row去保存每一行的实体。

<t:grid t:source="allCelebrities" rowsPerPage="5" row="celebrity"/>

当然在页面类中要有celebrity属性,我们就用Loop留下的那个。

接下来我们就要告诉tapestrygrid在渲染到lastname这一列的时候,我们不希望它按照默认的方式去显示,而要以我们的方式去显示

 

<t:grid t:source="allCelebrities" rowsPerPage="5" row="celebrity">

<t:parameter name="lastNameCell">

<t:pagelink t:page="details" t:context="celebrity.id">

${celebrity.lastName}

</t:pagelink>

</t:parameter>

</t:grid>

 

在这里,gird组件包含了一个特殊的Tapestry元素:<t:parameter/>,是不是和我们以前说IF组件是包含在IF组件中的那个提供另一种显示的内容的东西很象?在这里,它包含的内容将填补在last name这一列。Tapestry是怎么知道的?根据元素的名字:lastNameCell,这个名字的第一部分:lastName,就是要展示的类中的一个属性,最后一部分:Cell,告诉tapestry这个表格的单元的内容将显示我们指定的内容。

 

运行看看:

 

 

现在就剩下去掉我们不想要的列,和重新对表头进行排序了。我们将用到两个属性:Grid-removereorder。修改模板中的组件定义:

<t:grid t:source="celebritySource" rowsPerPage="5"

row="celebrity"

remove="id"

reorder="lastName,firstName,occupation,dateOfBirth">

<t:parameter name="lastNameCell">

<t:pagelink t:page="details" t:context="celebrity.id">

${celebrity.lastName}

</t:pagelink>

</t:parameter>

</t:grid>

 

现在再运行一下看看:

 

 

注:reorder不能删除列,如果你在reorder中忽略了一个列,那么这个列将现在是表格的最后。

十五:改变列的标题

列的标题是由Tapestry自动产生的,要想改变标题,最有效率的方法是利用资源文件。就我们在说select组件用到的。在app.properties中加上这么一行:

dateOfBirth-label=Birth Date

运行该程序,你会发现生日的标题改成了Birth Date,在这里通过附加-label所定义的值显示在了标题中。

现在对于大部分的要求你都可以调整grid组件去解决,并且在它的帮助下可以显示不同的对象。然而,还有一个问题:

SHOWALL.JAVA中的getAllCelebrities方法中加个输出语句:

 

public List<Celebrity> getAllCelebrities()

{

System.out.println("Getting all celebrities...");

return dataSource.getAllCelebrities();

}

 

目的是为了在调用这个方法的时候让我们知道。每当表格展示名人的时候,都会输出这么一句。

 

Gird组件有个source属性赋给一个allCelebrities值,所以它调用getAllCelebrities去获取显示的数据。注意,grid在这个方法后调用,收到了15条数据,但是它值显示5条。

点击第二页,我们看到gird又调用了getAllCelebrities方法,并且收到了所有的数据,还是只显示5条,同样的第三页,第四页也是如此。这是非常浪费资源的方式。

想象一下如果我没有10000条数据,并且这些数据都在一个远程的数据库上,那么这个请求会浪费我们极大的资源,特别是有2000页。

 

我们需要一种更有效率的方式去访问需要的名人们,一页又一页的,在第一页的时候取出要在第一页显示的数据,在第二页的时候就取出本该在第二页显示的数据……Tapestry为我们提供了这种方式,我们只要提供一个GridDataSource接口的实现。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值