我在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) [:]
答案 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