日期:2014-05-16  浏览次数:20407 次

jsf readonly解决办法

问题描述

jsf对readonly的支持不够好,如下所示的使用方式会导致<h:inputText 的值不能不能被提交。

?

<h:inputText value="#{EquipmentBB.test }" readonly="#{EquipmentBB.readonly }"></h:inputText>

<h:commandButton action="#{ EquipmentBB.setReadonly(false)}" value="提交">

</h:commandButton>

?

//EquipmentBB 被定义为request作用域

public class EquipmentBB implements Serializable {
??? private boolean readonly;//省略get set方法
??? private String test;

?

原因分析

jsf不支持readonly组件的提交,参见HtmlBasicRenderer 的解码方法,当组件是disabled或readonly时不会获取页面提交过来的值。

public void decode(FacesContext context, UIComponent component)

??? {

??????? if(!(component instanceof UIInput))

??????? {//非输入组件,忽略

??????????? return;

??????? }

??????? if(Util.componentIsDisabledOrReadonly(component))//#{EquipmentBB.readonly }执行该表达式获取值

??????? {

??????????? return;

??????? }

解决办法

1)将EquipmentBB的作用域换成session,这样在解码阶段#{EquipmentBB.readonly }就能返回正确的值。不建议提升作用域。增加<h:hidden value="#{EquipmentBB.test }" 也无法解决问题。

2)使用页面阶段事件,在ApplyRequest阶段前改变EquipmentBB.readonly的值,这样解码时#{EquipmentBB.readonly }就能获取正确的值了。

<f:view beforePhaseListener=”#{EquipmentBB.beforePhaseListener}”

EquipmentBB增加beforePhaseListener(PhaseEvent event)方法,在方法中将readonly设置成false,这样解码时就可以获取到值了。