<转>关于h:dataTable的使用
关于h:dataTable的使用基本用法
后台处理
可以在table的每一行增加操作用于处理当前行(比如删除当前行),也可以在table外增加操作处理整个table(更新整个table),页面代码如下:
我们可以有多种方式来处理
1】 传统的jsp方式,也是很多初学者首先想到的方式,这种方式本质上和以前的方式没有区别,只是披上了jsf的外衣而已,强烈建议不要使用。并且这样没有办法处理整个table,按以前的方式处理是相当的麻烦。
给每一行的操作增加参数,然后在后台提取该参数
<t:dataTable var="emp" .... > <h:commandLink id="editLink" action="#{employeeAction.prepareEdit}"> <h:outputText value="#{msg.edit}"/> <f:param name="id" value="#{emp.id}"/> </h:commandLink>
FacesContext context = FacesContext.getCurrentInstance(); Map map = context.getExternalContext().getRequestParameterMap(); String employeeID = (String) map.get("id");
2】 使用actionListener,来取得当前行的数据。整个表的处理很简单,直接获取list即可(参加方法3)
<h:commandLink> <f:actionListener type="net.java.OrderActionListener" /> <h:outputText value="Order" /> </h:commandLink>
public class orderActionListener implements ActionListener { public void processAction(ActionEvent anEvent) throws AbortProcessingException { YourBeanClass tmpBean = null; UIComponent tmpComponent = anEvent.getComponent(); while (null != tmpComponent && !(tmpComponent instanceof UIData)) { tmpComponent = tmpComponent.getParent(); } if (tmpComponent != null && (tmpComponent instanceof UIData)) { Object tmpRowData = ((UIData) tmpComponent).getRowData(); if (tmpRowData instanceof YourBeanClass) { tmpBean = (YourBeanClass) tmpRowData; //TODO Implementation of your method } }
3】 通过绑定tale,这样就可以在后台直接通过table来获取当前行了,而不像方法2那样通过事件来获得table
<h:dataTable binding="#{testSelectItems.table}" id="hotels" value="#{testSelectItems.list}" var="hot"> <h:column id="c1"> <f:facet name="header" id="f1">label</f:facet> <h:inputText id="bbb" value="#{hot.label}" required="true"/> </h:column> <h:column id="c2"> <f:facet name="header" id="f2">value</f:facet> <h:inputText id="aaa" value="#{hot.value}" required="true"/> </h:column> <h:column id="c3"> <f:facet name="header" id="f3">link</f:facet> <!- 处理当前行 <h:commandLink id="ccc" action="#{testSelectItems.actionTest1}" value="#{hot.value}"> xxx#{hot.label} </h:commandLink> </h:column> </h:dataTable> <!- 处理全部行 <h:commandButton action="#{testSelectItems.actionTest}"/> </h:form>
public class TestSelectItems { private UIData table=new UIData(); private List list; public List getList(){ System.out.println("---TestSelectItems-getList----1---"); if(list==null){ System.out.println("--TestSelectItems-getList-----2---"); list=new ArrayList(); SelectItem it=new SelectItem(); it.setLabel("lable1"); it.setValue("1"); list.add(it); it=new SelectItem(); it.setLabel("lable2"); it.setValue("2"); list.add(it); } return list; } //处理全部行 public void actionTest(){ System.out.println("----list.size():"+list.size()); System.out.println("--actionTest--"); } //处理单行 public void actionTest1(){ SelectItem dd=(SelectItem)table.getRowData(); System.out.println("--actionTest1--:"+dd.getLabel()); } public UIData getTable() { return table; } public void setTable(UIData table) { this.table = table; }
增加多选操作
目前的table只支持单行操作和全部行操作,而不支持多选操作,比如每行号前有个复选框,用于批量删除。
通常做法
通常的做法是改写值对象,或者改写值对象的基类,在其中增加checked属性
------------------------------------------------
public abstract class BaseObject implements Serializable { private boolean checked; public void setChecked(boolean value) { this.checked = value; } public boolean isChecked(){ return this.checked; } ... }
在页面上使用
<h:selectBooleanCheckbox value="#{e.checked}" /> <h:dataTable var="e" value="#{typeallList.typeallModel }"> <f:facet name="header"><h:outputText value="#{text['typeall.typelist'] }"/> </f:facet> <h:column> <f:facet name="header"><h:outputText value="#{text['list.checkall'] }"/></f:facet> <h:selectBooleanCheckbox value="#{e.checked}" /> </h:column>
提交后循环全部行,取出选择的行
public String removeChecked(){ List tempList = typeallModel.getWrappedObject(); for (int i=0;i<tempList.size();i++){ OaTypeall obj=(OaTypeall)tempList.get(i); if (obj.isChecked()) { //删除obj } return null; }
该方法的缺点是需要修改值对象,而添加的属性对值对象而言是没有意义的。这种方式破坏了对象的内聚性,把与该对象不相关的属性强添加到对象中。
新思路
页面使用方式不变,不用修改值对象的类,用ListCheckedDataModel封装list,在其中动态给list中的对象增加checked属性,并增加获取所以选择行的list。关键点是如何给值对象动态增加属性。可以考虑使用动态字节码操作javassist来动态增加字段
实现原理
(似乎作者未贴完)
页:
[1]