如果有条件地呈现JSF selectBooleanCheckbox则不调用关联的setter方法

时间:2011-09-20 20:21:49

标签: jsf

我在JBoss 6.1.0 final上使用Mojarra 2.0.3。我遇到了h的值setter方法的问题:如果在标记中指定了条件呈现,则不会调用selectBooleanCheckbox。

具体做法是:

JSF:

<h:selectBooleanCheckbox value="#{somebean.checked}" rendered="#{somebean.render}" />

示例bean代码:

private Boolean checked = new Boolean(false);

public Boolean getChecked() {return checked;}

public void setChecked(Boolean checked) {this.checked = checked;}

public boolean getRender() {return true;}

问题是在提交表单时从不调用setChecked()方法。如果我删除“rendered”属性,将按预期调用setter。只有在有条件地呈现标记时才会在提交时处理它。在任何一种情况下都会正常调用getter。

如果我设置了valueChangeListener,如果有条件地渲染selectBooleanCheckbox,也不会调用它。最后,将h:selectBooleanCheckbox标记包含在像:panelGrid这样的容器中,并在“outside”组件上设置条件呈现会导致相同的行为。如果有条件地呈现复选框,似乎不会处理该复选框。

这似乎是一种基本的东西,所以我假设有一些我缺少的东西。有没有人对此有类似的经历?

UPDATE :在这种情况下,托管bean是CDI ConversationScoped bean。进一步调试似乎表明bean的另一个实例在JSF生命周期中实例化并使用。所以我修改了bean,在postConstruct方法中将对话设置为非瞬态。这导致JSF在评估“呈现”属性中使用的EL表达式时抛出以下异常:

23:41:12,179 WARNING[javax.enterprise.resource.webcontainer.jsf.lifecycle] /admin/edit_user_profile.xhtml @41,72 rendered="#{profileEditor.isCurrentUser}": java.lang.IllegalStateException: javax.el.ELException: /admin/edit_user_profile.xhtml @41,72 rendered="#{profileEditor.isCurrentUser}": java.lang.IllegalStateException
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111) [:2.0.3-]
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:190) [:2.0.3-]
    at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:417) [:2.0.3-]
.
.
.
Caused by: java.lang.IllegalStateException
    at com.sun.faces.context.FacesContextImpl.assertNotReleased(FacesContextImpl.java:635) [:2.0.3-]
    at com.sun.faces.context.FacesContextImpl.getExternalContext(FacesContextImpl.java:135) [:2.0.3-]
    at com.sgi.tds.web.admin.beans.TdsAdminBean.getCurrentUser(TdsAdminBean.java:36) [:]
    at com.sgi.tds.web.admin.beans.UserProfileEditorBean.getIsCurrentUser(UserProfileEditorBean.java:153) [:]
    at com.sgi.tds.web.admin.beans.UserProfileEditorBean$Proxy$_$$_WeldClientProxy.getIsCurrentUser(UserProfileEditorBean$Proxy$_$$_WeldClientProxy.java) [:]

1 个答案:

答案 0 :(得分:2)

作为攻击保护的一部分,当JSF对表单提交进行后处理时,会重新评估rendered属性。它在您的特定情况下评估false只能意味着您的bean是请求范围的,并且您没有在bean的(post)构造函数中保留属性值。

如果你不能保留它,那么你需要将bean放在视图范围内。

@ManagedBean
@ViewScoped
public class Somebean {

    // ...
}

这样,只要您与同一视图进行交互,bean实例就会存在。另请参阅此相关问题/答案:commandButton/commandLink/ajax action/listener method not invoked or input value not updated