2007-08-21
T5 技巧 2:为Grid组件的每一行增加“删除/修改”链接。
关键字: tapestry
现在正在使用T5开发一个小项目。 因为现在T5还正处于发展中。 而且没有像T4一样有许多的文档。 和例子(Workbench, Vlib)。 所以我会把在这个开发中遇到的一些问题记录下来。
记得在T4中是使用一组字符串来作为table columns。 为了加上删除/修改按钮的话,我们就只要加上"!operation" 这样的字符串, 然后用block render td就行了。但是到了T5中。 并没有提供这样的属性。
在看了Grid组件的参数后。 我们发现model 这个参数。 毫无疑问这个参数是用来定义Bean中要显示的列, 是否排序, 显示的顺序 等等。 具体可以看org.apache.tapestry.beaneditor.BeanModel。org.apache.tapestry.services.BeanModelSource. org.apache.tapestry.beaneditor.PropertyModel. 这些接口和他们的实现类。
那我们要怎样增加这样的“删除/修改”列呢? 因为column必须是要在Bean中的一个property。 所以最直接的方法是在Bean中增加这样的一个假的属性。 比如。
ok. 这样我们就实现了这个“删除/修改”列。
但是大家可能都会觉得这样不爽。因为operationColumn污染了我们的User类。
下面介绍种不污染的方法。
我们还是要从model这个参数下手。。
我们需要build一个beanModel
在 page 类。
html template:
ok。
参考:http://www.nabble.com/T5---Adding-modify-delete-actions-to-a-Grid-t3370935.html#a9379935
记得在T4中是使用一组字符串来作为table columns。 为了加上删除/修改按钮的话,我们就只要加上"!operation" 这样的字符串, 然后用block render td就行了。但是到了T5中。 并没有提供这样的属性。
在看了Grid组件的参数后。 我们发现model 这个参数。 毫无疑问这个参数是用来定义Bean中要显示的列, 是否排序, 显示的顺序 等等。 具体可以看org.apache.tapestry.beaneditor.BeanModel。org.apache.tapestry.services.BeanModelSource. org.apache.tapestry.beaneditor.PropertyModel. 这些接口和他们的实现类。
那我们要怎样增加这样的“删除/修改”列呢? 因为column必须是要在Bean中的一个property。 所以最直接的方法是在Bean中增加这样的一个假的属性。 比如。
class User {
private int id;
private String name;
// add a fake property. However this property shouldn't use except in grid render.
private String operationColumn;
//...............other properties...........
// .................getter/setter methods
}
<t:parameter t:name="operationColumnCell"> <a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a> </t:parameter>
ok. 这样我们就实现了这个“删除/修改”列。
但是大家可能都会觉得这样不爽。因为operationColumn污染了我们的User类。
下面介绍种不污染的方法。
我们还是要从model这个参数下手。。
我们需要build一个beanModel
package com.javaeye.dengyin2000.gtts.tapestry;
import java.lang.annotation.Annotation;
import org.apache.tapestry.PropertyConduit;
public class OperationPC implements PropertyConduit {
public Object get(Object arg0) {
return "";
}
public Class getPropertyType() {
return String.class;
}
public void set(Object arg0, Object arg1) {
}
public <T extends Annotation> T getAnnotation(Class<T> arg0) {
return null;
}
}
public static BeanModel buildDriverBeanModel(BeanModelSource beanModelSource, ComponentResources componentSources){
if (driverBeanModel == null){
PropertyConduit operationPC = new OperationPC();
driverBeanModel = beanModelSource.create(Driver.class, false, componentSources);
driverBeanModel.remove("id", "sex", "photo", "address", "sexType", "national");
driverBeanModel.get("name").label("姓名").order(0);
driverBeanModel.get("idCard").label("身份证").order(1);
driverBeanModel.get("telNo").label("电话号码").order(2);
driverBeanModel.get("carNo").label("车牌号码").order(3);
driverBeanModel.get("carLong").label("车长(米)").order(4);
driverBeanModel.get("carWidth").label("车宽(米)").order(5);
driverBeanModel.get("carHeight").label("车高(米)").order(6);
driverBeanModel.add("operation", operationPC).label("操作").order(7).sortable(false);
}
return driverBeanModel;
}
在 page 类。
@Inject
private BeanModelSource beanModelSource;
@Inject
private ComponentResources componentSources;
..........................................
public BeanModel getDriverBeanModel(){
return MiscUtils.buildDriverBeanModel(beanModelSource, getComponentSources());
}
html template:
<table t:id="driverGrid" t:type="Grid" model="driverBeanModel" source="driverSource" row="currentRow" empty="nodata" pagerPosition="bottom" rowsPerPage="12" class="xx">
<t:parameter t:name="operationCell">
<a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a>
</t:parameter>
</table>
ok。
参考:http://www.nabble.com/T5---Adding-modify-delete-actions-to-a-Grid-t3370935.html#a9379935
评论
lococode
2007-09-20
dengyin2000 写道
lococode 写道
to:dengyin2000
关于标题所说的给Grid增加操作一列的问题,lz做法是一种方法,但是每个不同的grid都要buildDriverBeanModel一下,是否太复杂了?我们的做法是,每个页面有需要的话,会有一个form类,这里可以在Bean中的一个property,因为我们一开始就把hiernate实体类和页面需要的对象分开的。所以不存在污染bean的问题,而且这样更明确form类的功能。不过model.remove()还是需要用的。
关于Grid分页的实现,对于lz的实现方式,有几点不同意的地方:分页组件BussnissService 存在依赖的的关系,分页组件依赖hsql。
我的做法虽然让我自己现在还是不太满意,但是,至少,可以在一定程度上更加通用。
^_^!
关于标题所说的给Grid增加操作一列的问题,lz做法是一种方法,但是每个不同的grid都要buildDriverBeanModel一下,是否太复杂了?我们的做法是,每个页面有需要的话,会有一个form类,这里可以在Bean中的一个property,因为我们一开始就把hiernate实体类和页面需要的对象分开的。所以不存在污染bean的问题,而且这样更明确form类的功能。不过model.remove()还是需要用的。
关于Grid分页的实现,对于lz的实现方式,有几点不同意的地方:分页组件BussnissService 存在依赖的的关系,分页组件依赖hsql。
我的做法虽然让我自己现在还是不太满意,但是,至少,可以在一定程度上更加通用。
^_^!
有没有必要多加一个Form对象。 GridDataSource当然需要关联invoke bussniss Service 方法。 你可以说说你是怎样做的。你说hsql不应该出现, 你当然可以把hsql放到service方法中。 当然如果很多domain的话, 那么就有许多findXXX的方法了。
1.一个Pager对象,典型如下:
private List<T> elements; private int itemAmount; private int currentPageIndex; private int pageSize; public int getXXX ... public void setXXX .....
2.一个GridSourceModel 接口,留个具体的业务操作实现,典型代码如下:
//public Pager<T> getCurrentPager(); public Pager<T> getCurrentPager(int pageSize,int pageNo); //public void setCurrentPager(Pager<T> pager);
3.重新实现:GridDataSource
此中对象为
private final Pager<T> _pager;
而不是ListGridDataSource中的。
private final List _list;
4.contributeTypeCoercer
。。。。。
5.use:
items = new GridSourceModel<XXXObject>() {
public Pager<XXXObject> getCurrentPager(int pageSize, int pageNo) {
Pagination<XXXObject1> pus = manager.findXXX(XXx,pageSize,pageNo);
Pager<XXXObject> pager = getPager(pus);//Pagination -> Pager
return pager;
}
};
dengyin2000
2007-09-14
lococode 写道
to:dengyin2000
关于标题所说的给Grid增加操作一列的问题,lz做法是一种方法,但是每个不同的grid都要buildDriverBeanModel一下,是否太复杂了?我们的做法是,每个页面有需要的话,会有一个form类,这里可以在Bean中的一个property,因为我们一开始就把hiernate实体类和页面需要的对象分开的。所以不存在污染bean的问题,而且这样更明确form类的功能。不过model.remove()还是需要用的。
关于Grid分页的实现,对于lz的实现方式,有几点不同意的地方:分页组件BussnissService 存在依赖的的关系,分页组件依赖hsql。
我的做法虽然让我自己现在还是不太满意,但是,至少,可以在一定程度上更加通用。
^_^!
关于标题所说的给Grid增加操作一列的问题,lz做法是一种方法,但是每个不同的grid都要buildDriverBeanModel一下,是否太复杂了?我们的做法是,每个页面有需要的话,会有一个form类,这里可以在Bean中的一个property,因为我们一开始就把hiernate实体类和页面需要的对象分开的。所以不存在污染bean的问题,而且这样更明确form类的功能。不过model.remove()还是需要用的。
关于Grid分页的实现,对于lz的实现方式,有几点不同意的地方:分页组件BussnissService 存在依赖的的关系,分页组件依赖hsql。
我的做法虽然让我自己现在还是不太满意,但是,至少,可以在一定程度上更加通用。
^_^!
有没有必要多加一个Form对象。 GridDataSource当然需要关联invoke bussniss Service 方法。 你可以说说你是怎样做的。你说hsql不应该出现, 你当然可以把hsql放到service方法中。 当然如果很多domain的话, 那么就有许多findXXX的方法了。
lococode
2007-09-14
to:dengyin2000
关于标题所说的给Grid增加操作一列的问题,lz做法是一种方法,但是每个不同的grid都要buildDriverBeanModel一下,是否太复杂了?我们的做法是,每个页面有需要的话,会有一个form类,这里可以在Bean中的一个property,因为我们一开始就把hiernate实体类和页面需要的对象分开的。所以不存在污染bean的问题,而且这样更明确form类的功能。不过model.remove()还是需要用的。
关于Grid分页的实现,对于lz的实现方式,有几点不同意的地方:分页组件BussnissService 存在依赖的的关系,分页组件依赖hsql。
我的做法虽然让我自己现在还是不太满意,但是,至少,可以在一定程度上更加通用。
^_^!
关于标题所说的给Grid增加操作一列的问题,lz做法是一种方法,但是每个不同的grid都要buildDriverBeanModel一下,是否太复杂了?我们的做法是,每个页面有需要的话,会有一个form类,这里可以在Bean中的一个property,因为我们一开始就把hiernate实体类和页面需要的对象分开的。所以不存在污染bean的问题,而且这样更明确form类的功能。不过model.remove()还是需要用的。
关于Grid分页的实现,对于lz的实现方式,有几点不同意的地方:分页组件BussnissService 存在依赖的的关系,分页组件依赖hsql。
我的做法虽然让我自己现在还是不太满意,但是,至少,可以在一定程度上更加通用。
^_^!
lococode
2007-09-14
to:dengyin2000
第一眼看了你的 tapestry-grid.png 图,我吓了一跳,怎么谁把我们的项目的截图发出来了,仔细一看,哦,只是用了同一个html样式模板。
我们基于 Tapestry5.0.4 + spring + hibernate 基本一个项目做完了,有不少收获,但是 发现Tapestry 5 还是有不少问题的,也许由于时间的问题,不少问题我还未来的及解决;想在项目结束后,再好好的研究下。希望能共同学习。
第一眼看了你的 tapestry-grid.png 图,我吓了一跳,怎么谁把我们的项目的截图发出来了,仔细一看,哦,只是用了同一个html样式模板。
我们基于 Tapestry5.0.4 + spring + hibernate 基本一个项目做完了,有不少收获,但是 发现Tapestry 5 还是有不少问题的,也许由于时间的问题,不少问题我还未来的及解决;想在项目结束后,再好好的研究下。希望能共同学习。
dengyin2000
2007-09-06
match927 写道
那里有PropertyConduit类的API
这几个方法是干什么的?
多谢
public Object get(Object arg0) ;
public Class getPropertyType() ;
public void set(Object arg0, Object arg1) ;
public <T extends Annotation> T getAnnotation(Class<T> arg0) ;
这几个方法是干什么的?
多谢
你看了这个class 的java doc吗? 不要跟我说你看不懂英语。
/**
* Used to read or update the value associated with a property. A PropertyConduit provides access to
* the annotations on the underlying getter and/or setter methods.
*/
public interface PropertyConduit extends AnnotationProvider
{
/**
* Reads the property from the instance.
*
* @param instance
* object containing the property
* @return the current value of the property
*/
Object get(Object instance);
/**
* Changes the current value of the property.
*
* @param instance
* object containing the property
* @param value
* to change the property to
*/
void set(Object instance, Object value);
/** Returns the type of the property read or updated by the conduit. */
Class getPropertyType();
}
dengyin2000
2007-09-06
match927 写道
to:all
若User对象中有个日期型的变量,它在 grid 中未展示,应该怎么处理呢?
若User对象中有个日期型的变量,它在 grid 中未展示,应该怎么处理呢?
你可以象上面那样自定义Date column的输出。 在你的page中定义一个方法 使用DateFormat格式化输出。。
match927
2007-09-05
那里有PropertyConduit类的API
这几个方法是干什么的?
多谢
public Object get(Object arg0) ;
public Class getPropertyType() ;
public void set(Object arg0, Object arg1) ;
public <T extends Annotation> T getAnnotation(Class<T> arg0) ;
这几个方法是干什么的?
多谢
match927
2007-09-05
to:all
若User对象中有个日期型的变量,它在 grid 中未展示,应该怎么处理呢?
若User对象中有个日期型的变量,它在 grid 中未展示,应该怎么处理呢?
match927
2007-08-29
to:dengyin2000
非常感谢,正确的应该是:
<t:parameter t:name="${property}Cell">
<a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a>
</t:parameter>
非常感谢,正确的应该是:
<t:parameter t:name="${property}Cell">
<a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a>
</t:parameter>
match927
2007-08-29
to:dengyin2000
非常感谢,正确的应该是:
非常感谢,正确的应该是:
<t:parameter t:name="${property}Cell">
<a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a>
</t:parameter>
dengyin2000
2007-08-28
<t:parameter t:name="${property}ColumnCell">
<a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a>
</t:parameter>
<a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a>
</t:parameter>
match927
2007-08-28
大家帮我看下,为什么链接不出来,我想在grid建个链接,谢谢
<table t:type="grid" source="persons" rowsPerPage="5" row="person">
<t:parameter t:name="name">
<t:ActionLink t:id="view" context="person.name">${person.name}</t:ActionLink>
</t:parameter>
</table>
public class Person {
private String name;
private int age;
public Person()
{
this.name = "aspire";
this.age = 2008;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}public class Start {
private Person person;
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
private Person[] persons;
public Person[] getPersons() {
if ( null == persons)
{
persons = new Person[]{new Person(), new Person()};
}
return persons;
}
public void setPersons(Person[] persons) {
this.persons = persons;
}
}
dengyin2000
2007-08-25
BussnissService 这个是业务Service 类。 给你也没有用。
service.pagedQuery 是根据startIndex endIndex 去数据库拿一页的数据。
BasePage 是我写的一个基类。
service.pagedQuery 是根据startIndex endIndex 去数据库拿一页的数据。
BasePage 是我写的一个基类。
hitalang
2007-08-25
看了你的文章,我非常感谢你的慷慨相授,我由于初学tapestry5,而且t4没有学过,t5刚刚学习,很多都是看网友的文章之后修改得来的,你的也被我“抄袭了”,脸红呀,可是好奇心促使我还想看更多的东西,你这个是t5下的吗,public class Drivers extends BasePage 好像是t4的,
另外,import com.javaeye.dengyin2000.gtts.genericdao.Page;
import com.javaeye.dengyin2000.gtts.service.BussnissService; 这两个类,能贴出来吗,谢谢

另外,import com.javaeye.dengyin2000.gtts.genericdao.Page;
import com.javaeye.dengyin2000.gtts.service.BussnissService; 这两个类,能贴出来吗,谢谢
hitalang
2007-08-25
使用默认的grid不行吗???
dengyin2000
2007-08-25
hitalang 写道
非常感谢你的分享,我在用grid控件,页面为典型的主/从查询页面,从主传输参数过来到从,从页面用grid,结果也能够查出来,但是分页出了问题,就是说第一页码,可以有结果,但是点击第二页时候,没有显示,搂主能不能帮助解决一下,谢谢
我不知道你是怎样实现GridDataSource的。。
我贴下我的吧。
package com.javaeye.dengyin2000.gtts.utils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.tapestry.beaneditor.PropertyModel;
import org.apache.tapestry.grid.GridDataSource;
import com.javaeye.dengyin2000.gtts.domain.Driver;
import com.javaeye.dengyin2000.gtts.genericdao.Page;
import com.javaeye.dengyin2000.gtts.service.BussnissService;
public class DriverGridDataSource implements GridDataSource {
private String nameQueryString;
private int pageSize;
private BussnissService service;
private int totalCount;
private Map<Integer, Driver> currentDatas = new HashMap<Integer, Driver>();
public DriverGridDataSource(String string, int pageSize, BussnissService service){
this.nameQueryString = string;
this.pageSize = pageSize;
this.service = service;
}
public int getAvailableRows() {
if (totalCount == 0)
this.totalCount = service.getDomainsCount(getHqlString(), getParams());
return totalCount;
}
public Class getRowType() {
return Driver.class;
}
public Object getRowValue(int index) {
return currentDatas.get(index);
}
@SuppressWarnings("unchecked")
public void prepare(int startIndex, int endIndex, PropertyModel sortModel,
boolean ascending) {
Page page = null;
if (sortModel == null)
page = service.pagedQuery(getHqlString(), startIndex, pageSize, null, false, getParams(), this.totalCount);
else
page = service.pagedQuery(getHqlString(), startIndex, pageSize, sortModel.getPropertyName(), ascending, getParams(),this.totalCount);
List<Driver> result = (List<Driver>) page.getResult();
currentDatas.clear();
for(int i=0; i<result.size(); i++){
currentDatas.put(startIndex+i, result.get(i));
}
}
private String getHqlString(){
String hql = "from Driver where 1=1";
if (StringUtils.isNotBlank(nameQueryString)){
hql = hql + " and name like :name";
}
return hql;
}
private Map<String, Object> getParams(){
Map<String, Object> params = new HashMap<String, Object>();
if (StringUtils.isNotBlank(nameQueryString)){
params.put("name", "%" + nameQueryString + "%");
}
return params;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
}
package com.javaeye.dengyin2000.gtts.pages.basicinformation;
import java.util.ArrayList;
import java.util.List;
import org.apache.tapestry.Block;
import org.apache.tapestry.annotations.Component;
import org.apache.tapestry.annotations.Inject;
import org.apache.tapestry.annotations.Persist;
import org.apache.tapestry.beaneditor.BeanModel;
import org.apache.tapestry.corelib.components.Grid;
import org.apache.tapestry.grid.GridDataSource;
import org.apache.tapestry.services.BeanModelSource;
import com.javaeye.dengyin2000.gtts.base.BasePage;
import com.javaeye.dengyin2000.gtts.domain.Driver;
import com.javaeye.dengyin2000.gtts.utils.DriverGridDataSource;
import com.javaeye.dengyin2000.gtts.utils.MiscUtils;
public class Drivers extends BasePage {
@Inject
private BeanModelSource beanModelSource;
@Inject
private Block nodata;
@Component(id="driverGrid")
private Grid driverGrid;
private String driverName;
private Driver currentRow;
@Persist
private GridDataSource dataSource;
public String getDriverName() {
return driverName;
}
public void setDriverName(String driverName) {
this.driverName = driverName;
}
public BeanModel getDriverBeanModel(){
return MiscUtils.buildDriverBeanModel(beanModelSource, getComponentSources());
}
public GridDataSource getDriverSource(){
if (dataSource == null) {
dataSource = new DriverGridDataSource(getDriverName(), driverGrid.getRowsPerPage(), getBussnissService());
}
// fouce the grid to refetch the count;
((DriverGridDataSource)dataSource).setTotalCount(0);
return dataSource;
}
void onActionFromDeleteLink(int driverId){
List<Integer> deleteIds = new ArrayList<Integer>();
deleteIds.add(driverId);
getBussnissService().deleteDrivers(deleteIds);
setMessage("删除成功!");
}
public Block getNodata() {
return nodata;
}
public Driver getCurrentRow() {
return currentRow;
}
public void setCurrentRow(Driver currentRow) {
this.currentRow = currentRow;
}
}
hitalang
2007-08-25
非常感谢你的分享,我在用grid控件,页面为典型的主/从查询页面,从主传输参数过来到从,从页面用grid,结果也能够查出来,但是分页出了问题,就是说第一页码,可以有结果,但是点击第二页时候,没有显示,搂主能不能帮助解决一下,谢谢
hitalang
2007-08-23
谢谢,能不能讲讲下拉框,。。。
dengyin2000
2007-08-23
match927 写道
TO: dengyin2000
能否整理个完整的"为Grid组件的每一行增加“删除/修改”链接"。
非常感谢。
能否整理个完整的"为Grid组件的每一行增加“删除/修改”链接"。
非常感谢。
有哪里不懂? 我应该算讲得比较详细吧,。
match927
2007-08-23
TO: dengyin2000
能否整理个完整的"为Grid组件的每一行增加“删除/修改”链接"。
非常感谢。
能否整理个完整的"为Grid组件的每一行增加“删除/修改”链接"。
非常感谢。
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 220280 次
- 性别:

- 来自: 广州

- 详细资料
搜索本博客
我的相册
VB-seamless
共 13 张
共 13 张
最近加入圈子
最新评论
-
使用Terracotta和Tomcat建 ...
renavatior 写道"运行start.bat 9081 这样我们就启动了目 ...
-- by rainsf -
使用Terracotta和Tomcat建 ...
"运行start.bat 9081 这样我们就启动了目录9081中的tomcat ...
-- by renavatior -
广州3年多经验 5500的 ...
fucku 写道广州的软件厂家可比深圳多多了,不过比起北京上海来,还是少了很多, ...
-- by yongfan_420 -
广州3年多经验 5500的 ...
广州的软件厂家可比深圳多多了,不过比起北京上海来,还是少了很多,导致机会也没有这 ...
-- by fucku -
广州3年多经验 5500的 ...
想高工资就去厂家咯,老在集成商里面混能有多大个奔头
-- by fucku






评论排行榜