`
dengyin2000
  • 浏览: 1228366 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

T5 技巧 2:为Grid组件的每一行增加“删除/修改”链接。

阅读更多
现在正在使用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中增加这样的一个假的属性。  比如。

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);
			
			[color=red][b]driverBeanModel.add("operation", operationPC).label("操作").order(7).sortable(false);[/b][/color]
		}
		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">
[color=red][b]				<t:parameter t:name="operationCell">
					<a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a>
				</t:parameter>[/b][/color]
			</table>




ok。

参考:http://www.nabble.com/T5---Adding-modify-delete-actions-to-a-Grid-t3370935.html#a9379935
分享到:
评论
32 楼 lococode 2007-09-20  
dengyin2000 写道
lococode 写道
to:dengyin2000
关于标题所说的给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;
		}
};
31 楼 dengyin2000 2007-09-14  
lococode 写道
to:dengyin2000
关于标题所说的给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的方法了。
30 楼 lococode 2007-09-14  
to:dengyin2000
关于标题所说的给Grid增加操作一列的问题,lz做法是一种方法,但是每个不同的grid都要buildDriverBeanModel一下,是否太复杂了?我们的做法是,每个页面有需要的话,会有一个form类,这里可以在Bean中的一个property,因为我们一开始就把hiernate实体类和页面需要的对象分开的。所以不存在污染bean的问题,而且这样更明确form类的功能。不过model.remove()还是需要用的。
关于Grid分页的实现,对于lz的实现方式,有几点不同意的地方:分页组件BussnissService 存在依赖的的关系,分页组件依赖hsql。
我的做法虽然让我自己现在还是不太满意,但是,至少,可以在一定程度上更加通用。
^_^!
29 楼 lococode 2007-09-14  
to:dengyin2000
第一眼看了你的  tapestry-grid.png 图,我吓了一跳,怎么谁把我们的项目的截图发出来了,仔细一看,哦,只是用了同一个html样式模板。

我们基于 Tapestry5.0.4 + spring + hibernate 基本一个项目做完了,有不少收获,但是 发现Tapestry 5 还是有不少问题的,也许由于时间的问题,不少问题我还未来的及解决;想在项目结束后,再好好的研究下。希望能共同学习。
28 楼 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();
}
27 楼 dengyin2000 2007-09-06  
match927 写道
to:all

若User对象中有个日期型的变量,它在 grid 中未展示,应该怎么处理呢?


你可以象上面那样自定义Date column的输出。   在你的page中定义一个方法  使用DateFormat格式化输出。。
26 楼 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) ;

这几个方法是干什么的?
多谢
25 楼 match927 2007-09-05  
to:all

若User对象中有个日期型的变量,它在 grid 中未展示,应该怎么处理呢?
24 楼 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>
23 楼 match927 2007-08-29  
to:dengyin2000
非常感谢,正确的应该是:
<t:parameter t:name="[color=red]${property}Cell[/color]">
<a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a>
</t:parameter>
22 楼 dengyin2000 2007-08-28  
<t:parameter t:name="${property}ColumnCell"> 
                     <a t:type="ActionLink" t:id="deleteLink" context="currentRow.id">删除</a> 
                 </t:parameter>
21 楼 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;
	}
	
	
}
20 楼 dengyin2000 2007-08-25  
BussnissService  这个是业务Service 类。  给你也没有用。

service.pagedQuery  是根据startIndex endIndex 去数据库拿一页的数据。

BasePage 是我写的一个基类。
19 楼 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; 这两个类,能贴出来吗,谢谢 
18 楼 hitalang 2007-08-25  
使用默认的grid不行吗???
17 楼 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;
	}
}

16 楼 hitalang 2007-08-25  
非常感谢你的分享,我在用grid控件,页面为典型的主/从查询页面,从主传输参数过来到从,从页面用grid,结果也能够查出来,但是分页出了问题,就是说第一页码,可以有结果,但是点击第二页时候,没有显示,搂主能不能帮助解决一下,谢谢
15 楼 hitalang 2007-08-23  
谢谢,能不能讲讲下拉框,。。。
14 楼 dengyin2000 2007-08-23  
match927 写道
TO:  dengyin2000

能否整理个完整的"为Grid组件的每一行增加“删除/修改”链接"。
非常感谢。


有哪里不懂?  我应该算讲得比较详细吧,。 
13 楼 match927 2007-08-23  
TO:  dengyin2000

能否整理个完整的"为Grid组件的每一行增加“删除/修改”链接"。
非常感谢。

相关推荐

    友价T5商城源码支持app 带个人免签约支付接口友价T5商城源码

    最新带个人免签约支付接口友价T5商城源码,支持app上传功能,源码交易网源码,站长交易网 独家修复后台设置虚拟数据后首页不生效,新加个人免签约支付接口---码支付接口! 码支付接口是个人支付宝 微信 QQ 收款,全自动...

    T5UIC2 开发指南_V20.pdf

    T5UIC2软件平台以其精简的指令集和灵活的配置选项,为开发者提供了一个高效的人机界面解决方案。 首先,T5UIC2支持多种尺寸的串口屏硬件型号,从2.8寸到12.1寸不等,提供了丰富的分辨率选项,满足不同应用场景下的...

    National Talent Search Examination

    自1961年NCERT成立以来,就启动了一个名为“国家科学天才搜索计划”(NSTSS)的项目,旨在识别和培养优秀学生,并为他们提供奖学金。该计划最初仅限于当时的德里联邦直辖区,第一年仅向11年级的学生颁发了10个奖学金...

    spart T5-2 solaris

    Sparc T5-2 是一款由Sun Microsystems(后被Oracle公司收购)设计的高性能服务器平台,专为关键业务和数据中心应用而构建。该服务器基于SPARC架构,提供卓越的计算能力、内存容量和I/O性能。Sparc T5-2 的核心亮点...

    共享汽车管理系统 JAVA+Vue+SpringBoot+MySQL

    项目录屏:https://www.bilibili.com/video/BV1xx4y187t5 启动教程:https://www.bilibili.com/video/BV1pW4y1P7GR 项目讲解视频:https://space.bilibili.com/417412814/channel/collectiondetail?sid=2242844

    基于T5-small的问答模型 它实际上是QuestEval指标的一个组成部分,但可以按原样独立使用,仅用于 QA

    2. **编码**:将预处理后的输入馈送给T5-Small模型,模型将其转换为内部表示。 3. **解码**:模型根据编码的输入生成答案序列。 4. **后处理**:将模型生成的文本序列转化为实际答案,并进行必要的清理或修剪。 **...

    cisco IOS下载链接大全

    Cisco IOS(Internetwork Operating System)是思科系统为大部分路由器及部分交换机等网络设备所开发的一种专有操作系统。它负责控制并管理设备的各项功能,如数据包转发、路由选择等。Cisco IOS采用模块化设计,...

    t5-pegasus:中文生成式预训练模型

    T5飞马 中文生成式预训练模型,以mT5为基础架构和初始权重,通过类似PEGASUS的方式进行预训练。 详情可见: ://kexue.fm/archives/8209 分词器 我们将T5 PEGASUS的令牌...目前开源的T5 PEGASUS是基本版,总参数量为2

    T5-2文本安装

    T5-2文本安装旨在为用户提供一个简洁、高效且易于自动化管理的安装方法。 ### 安装语言的选择 在开始安装之前,首先需要选择安装语言。这一步非常重要,因为它会影响到后续安装过程中显示的所有文本内容的语言版本...

    Bart_T5-summarization:使用Bart和T5模型的汇总任务

    Bart_T5-摘要使用来自Bart和T5模型的汇总任务可以直接比较文本摘要Bart和T5的最佳模型。安装需求pip install -U transformerspip install -U torchpip install flask跑步python app.py巴特总结T5总结

    思维导图模板免费分享-迅捷思维导图

    专为小学生设计的数学学习辅助材料,通过简单的图形和文字解释了除法的基本概念及其应用场景,有助于孩子快速掌握除法运算技巧。 **链接**: [http://app.siweidaotu.com/#R0d217b86d4f982a63be8f34ba6e06313]...

    GNUVario-TTGO-T5-website:GNUVario-TTGO-T5-网站

    【GNUVario-TTGO-T5-website:GNUVario-TTGO-T5-网站】是一个专注于GNUVario-E项目的在线资源平台,该平台致力于提供基于ESP32芯片的开源硬件设计和变量计的详细信息。这个项目的核心是将开源精神应用于电子工程领域...

    T5 + Hibernate 用户登陆2

    【标题】"T5 + Hibernate 用户登陆2"指的是在使用T5框架的基础上,结合Hibernate ORM技术实现用户登录功能的一个教程或案例。T5通常是指一个Web开发框架,而Hibernate则是一个流行的Java对象关系映射(ORM)工具,...

    T5LCFG汇总(仅参考)20200219_DWIN迪文T5L配置文件CFG_源码

    这个标题“T5LCFG汇总(仅参考)20200219_DWIN迪文T5L配置文件CFG_源码”指的是一个关于DWIN迪文T5L显示屏的配置文件集合,主要用于2020年2月19日的一个参考资料。这个压缩包包含了用于配置DWIN迪文T5L屏幕的不同...

    迪文T5L Keil C51项目模板.rar

    迪文T5L是一款基于8051内核的微控制器,由迪文科技公司设计生产,常用于工业控制、智能家居、消费电子等领域。Keil C51是针对8051系列微控制器的集成开发环境,它集成了编译器、调试器和IDE,使得C语言编程变得简单...

    谷歌FLAN-T5作者亲讲:5400亿参数,1800个任务,如何实现大语言模型“自我改进”_鲟曦研习社.pdf

    知识点2:Prompting方法可以预示着针对大模型的下游微调,将成为研究领域关注的重点。 知识点3:Chain of Thought(CoT)是一种最新的Prompting机制,可以让语言模型有了自我改进的能力。 知识点4:谷歌研究者们...

    03-Microsoft Teams 产品资源和技术社区1

    Microsoft Teams 是微软推出的一款团队协作平台,它集成了聊天、会议、电话、文件共享和应用集成等多种功能,旨在提升企业内部沟通与协作效率。本文将详细介绍Microsoft Teams的开发入门、实践资源以及技术社区,...

    ippicv_2017u3_lnx_intel64_general_20180518.tgz和20170822

    网上比较多的ippicv是ippicv_2017u3_lnx_intel64_general_...其实更万能的方式参考该链接:https://www.wandouip.com/t5i170326/ 特别注意file://这个是cmake读取文件的方式,所以 "file:///home/lc/下载/"是没错的

Global site tag (gtag.js) - Google Analytics