JSF在使用customize tag时不可以在其中添加<f:attribute> 的解决办法

这篇文章只限于在JSF1.2 下的一种特殊情况。 由于JSF2.0 以后EL支持用户在method里加argument, 所以不可以使用<f:attribute>的办法可以直接换成在EL中直接用argument pass那个特定的attribute.


problem define:

 在使用jsf的时候常常我们需要自己cunstomize tag, 但是问题是在customize tag的时候不容易给<f:attribute>留接口, 因为很多情况下一个customized tag里会包含好几个其他的tag, 所以让<f:attribute>这种在每个tag中都会出现的tag变得很难定义。所以在这种情况下,这种customized tag里是不会给<f:attribute>这样的tag留接口的。


但是这并不意味着我们在用customized tag的时候不可以使用<f:attribute>。 


解决办法:

假设现在我们需要在JSF page中做个表格,表格中每一行显示某一个项目从第一年到第九年的花费, 而每个列显示若干个项目在某一特定年份的花费 。 可能只显示数字看着比较单调, 所以我们在表格中的每个column里使用我们自己定义的一个tag, 例如 <ctm:customizedInputText>,来显示出具体的金额并且显示金额符号。如下

descriptionYear1Year2...Year9
food expense2000$1800$...1700$
drink expense1600$1400$...1500$
total3600$3200$...3200$

为了区分total 那个row 和 其他的row, 那么我们也需要一个变量来定义这个row, 假设我用下边的class来给表格赋值:

Class Order{

String description ;

Map<String, BigDecimal> amount;

boolean total;

}


然后List 里储存的数据会是这样的

{

description: "food expense" , amoutMap:{ row1:2000 ,  row2:1800 ... row9: 1700},  total:false

description: "drink expense" , amoutMap:{ row1:1600,  row2:1400... row9: 1500},  total:false

description: "total" , amoutMap:{ row13600 ,  row2:3200 ... row9:3200},  total:true

}


假设现在我们需要在用户在表格中任意一个customizedInputText中从新输入值的时候计算出这个列的总价格,那我们需要在我们自己的customizedInputText里extend原本<h:inputText> 的 valueChangeListener, 然后在backing bean中定义这个listener用来计算total row 的值,所以用户并不需要填写total那行的值, 而那一行会被自动计算出来

 那我们的代码大概会是这样的

<h:dataTable value="#{order.orderList}" var="row">
    <h:column id = "col_discription">
        <f:facet name="header">description</f:facet>
  <ctm:customizedTextField value="#{row.description}"/> </h:column>
     <h:column id = "col1">
        <f:facet name="header">year1</f:facet> 
        <ctm:customizedTextField value="#{row.amountMap["row1"]}" readOnly="row.total" valueChangeListener="calculateColumn1"/>
     </h:column> 
     <h:column id = "col2">
        <f:facet name="header">year2</f:facet>
        <ctm:customizedTextField value="#{row.amountMap["row2"]}" readOnly="row.total" valueChangeListener="calculateColumn2"/> 
     </h:column> ..... 
     <h:column id = "col9">
        <f:facet name="header">year9</f:facet>
        <ctm:customizedTextField value="#{row.amountMap["row9"]}" readOnly="row.total" valueChangeListener="calculateColumn9"/> 
    </h:column>
</h:table>

上边的代码是完全可行的, 但是有个很严重的问题, 就是我们有几个列就必须定义几个valueChangeListener, 这样会使代码变的难以维护。 如果不是使用customized tag, 我们可以用以下方法给valueChangeListener一个值, 这样一来我们就只用定义一个valueChangeListener:

<h:inputText value="#{row.amountMap["row1"]}" readOnly="row.total" valueChangeListener="calculateColumnTotal">
   <f:attribute name="columnName" value="column1" >
</h:inputText>

然后在我们的backing bean 里, 用下面的方法就能把设置的attribute拿出来

public void calculateColumnTotal(ValueChangeEvent event){
       String attribute = (String) event.getComponent().getAttributes().get("attributeName");
//handle change via attribute retrieved 
}



但是由于customized tag没办法用上述方法直接得到attribute的值, 所以得需要特殊一点的方法来获取。 下边是这个问题的解法:

1) 把customized tag 放到一个<h:panelGroup> 里,然后在那个panelGroup里定义你想要的attribute 如下:

<h:dataTable value="#{order.orderList}" var="row">
    <h:column id = "col_discription">
	    <f:facet name="header">description</f:facet>
		<h:panelGroup id="col1pl">
			<ctm:customizedTextField value="#{row.description}"/> </h:column>
			
     <h:column id = "col1">
        <f:facet name="header">year1</f:facet> 
		<h:panelGroup id="col1pl">
			<ctm:customizedTextField value="#{row.amountMap["row1"]}" readOnly="row.total" valueChangeListener="calculateColumn"/>
			<attribute name="column" value="COL1"/>
		</h:panelGroup>
     </h:column> 
     <h:column id = "col2">
        <f:facet name="header">year2</f:facet>
		<h:panelGroup id="col2pl">
			<ctm:customizedTextField value="#{row.amountMap["row2"]}" readOnly="row.total" valueChangeListener="calculateColumn"/> 
			<attribute name="column" value="COL2"/>
		</h:panelGroup>
     </h:column> ..... 
     <h:column id = "col9">
        <f:facet name="header">year9</f:facet>
		<h:panelGroup id="col9pl">
			<ctm:customizedTextField value="#{row.amountMap["row9"]}" readOnly="row.total" valueChangeListener="calculateColumn"/> 
			<attribute name="column" value="COL9"/>
		</h:panelGroup>
    </h:column>
</h:table>

然后在valueChangeListener里用如下方法就能获取到attribute的值:

public void calculateColumnTotal(ValueChangeEvent event){
       String attribute = (String) event.getComponent().getParent().getParent().getAttributes().get("attributeName");
//handle change via attribute retrieved 
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值