Primefaces:有条件渲染的组件没有被提交
Primefaces: conditionally rendered component doesn't get submitted
我有一个基于下拉列表有条件地呈现的字段。所有这些都没有问题,但是当我提交新呈现的组件应该属于的表单时,它没有被提交。
代码相当简单:
<h:form id="form">
<p:layout id="layout">
...
<p:layoutUnit id="layoutUnit">
...
<p:panel id="panel">
<p:outputPanel id="container1">
<p:selectOneMenu id="value1" value="#{bean.value1}">
<f:selectItem itemValue="1"/>
<f:selectItem itemValue="2"/>
<f:selectItem itemValue="3"/>
<f:selectItem itemValue="18"/>
<p:ajax event="change" update="container2"/>
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel id="container2">
<p:inputText id="value2"
value="#{bean.value2}"
rendered="#{bean.value1 eq 18}"
>
</p:inputText>
</p:outputPanel>
</panel>
<div id="buttons">
<p:commandButton id="commandButton" action="#{bean.save}" value="save" />
</div>
</layoutUnit>
</layout>
</form>
尝试过的可能解决方案:
- JSF的@ViewScoped无法使用,因为它与CDI冲突
- JSF Dynamic Rendered Component's Value becomes null when the form is submitted
- conditionally rendered input component does not update value
- commandButton/commandLink/ajax action/listener method not invoked or input value not updated
我能想到导致这种行为的几种情况:
- 'Rendered' 似乎根据支持 bean 中的值重新评估,
而不是 UI 中给出的新值(如果默认为 1,则提交时再次为 1,而不是 18)。因此该组件
没有提交。
- 添加的组件未正确添加到
表格,因此未提交。
- ?
选项 1 似乎是最有可能的,但谁能指出正确的方向?
我使用 WAS8.5(所以是 JSF2.0)、Primefaces 和 CDI。
除了@Named 之外,还使用CDI 的@ConversationScoped 是一种解决方案。该范围可与 JSF 的 @ViewScoped 相媲美。
为了使其正常工作,我只是添加了示例 here 中的代码。简而言之:
Bean.java
@Named
@ConversationScoped
public class Bean implements Serializable{
@Inject
private Conversation conversation;
Bean values, getters & setters
public void initConversation(){
if (!FacesContext.getCurrentInstance().isPostback() && conversation.isTransient()) {
conversation.begin();
}
}
public String endConversation(){
if(!conversation.isTransient()){
conversation.end();
}
}
public String navigateAwayFromScreen(){
endConversation();
}
}
beanOutput.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:event listener="#{bean.initConversation}" type="preRenderView"/>
<h:form id="form">
<p:layout id="layout">
...
<p:layoutUnit id="layoutUnit">
...
<p:panel id="panel">
<p:outputPanel id="container1">
<p:selectOneMenu id="value1" value="#{bean.value1}">
<f:selectItem itemValue="1"/>
<f:selectItem itemValue="2"/>
<f:selectItem itemValue="3"/>
<f:selectItem itemValue="18"/>
<p:ajax event="change" update="container2"/>
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel id="container2">
<p:inputText id="value2"
value="#{bean.value2}"
rendered="#{bean.value1 eq 18}"
>
</p:inputText>
</p:outputPanel>
</panel>
<div id="buttons">
<p:commandButton id="commandButton" action="#{bean.navigateAwayFromScreen}" value="Go away!" />
</div>
</layoutUnit>
</layout>
</form>
</html>
现在,对话在您打开页面时开始(由于从 beanOutput.xhtml 的顶部调用了 initConversation),并在您单击按钮 navigateAwayFromScreen 时结束。
(但是,如果您能够使用 JSF2.2,则应该可以将 @ViewScoped 与 CDI 结合使用。(我说 'should':我不适合升级.不过可能对别人检查有用)).
我有一个基于下拉列表有条件地呈现的字段。所有这些都没有问题,但是当我提交新呈现的组件应该属于的表单时,它没有被提交。
代码相当简单:
<h:form id="form">
<p:layout id="layout">
...
<p:layoutUnit id="layoutUnit">
...
<p:panel id="panel">
<p:outputPanel id="container1">
<p:selectOneMenu id="value1" value="#{bean.value1}">
<f:selectItem itemValue="1"/>
<f:selectItem itemValue="2"/>
<f:selectItem itemValue="3"/>
<f:selectItem itemValue="18"/>
<p:ajax event="change" update="container2"/>
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel id="container2">
<p:inputText id="value2"
value="#{bean.value2}"
rendered="#{bean.value1 eq 18}"
>
</p:inputText>
</p:outputPanel>
</panel>
<div id="buttons">
<p:commandButton id="commandButton" action="#{bean.save}" value="save" />
</div>
</layoutUnit>
</layout>
</form>
尝试过的可能解决方案:
- JSF的@ViewScoped无法使用,因为它与CDI冲突
- JSF Dynamic Rendered Component's Value becomes null when the form is submitted
- conditionally rendered input component does not update value
- commandButton/commandLink/ajax action/listener method not invoked or input value not updated
我能想到导致这种行为的几种情况:
- 'Rendered' 似乎根据支持 bean 中的值重新评估, 而不是 UI 中给出的新值(如果默认为 1,则提交时再次为 1,而不是 18)。因此该组件 没有提交。
- 添加的组件未正确添加到 表格,因此未提交。
- ?
选项 1 似乎是最有可能的,但谁能指出正确的方向?
我使用 WAS8.5(所以是 JSF2.0)、Primefaces 和 CDI。
除了@Named 之外,还使用CDI 的@ConversationScoped 是一种解决方案。该范围可与 JSF 的 @ViewScoped 相媲美。
为了使其正常工作,我只是添加了示例 here 中的代码。简而言之:
Bean.java
@Named
@ConversationScoped
public class Bean implements Serializable{
@Inject
private Conversation conversation;
Bean values, getters & setters
public void initConversation(){
if (!FacesContext.getCurrentInstance().isPostback() && conversation.isTransient()) {
conversation.begin();
}
}
public String endConversation(){
if(!conversation.isTransient()){
conversation.end();
}
}
public String navigateAwayFromScreen(){
endConversation();
}
}
beanOutput.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:event listener="#{bean.initConversation}" type="preRenderView"/>
<h:form id="form">
<p:layout id="layout">
...
<p:layoutUnit id="layoutUnit">
...
<p:panel id="panel">
<p:outputPanel id="container1">
<p:selectOneMenu id="value1" value="#{bean.value1}">
<f:selectItem itemValue="1"/>
<f:selectItem itemValue="2"/>
<f:selectItem itemValue="3"/>
<f:selectItem itemValue="18"/>
<p:ajax event="change" update="container2"/>
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel id="container2">
<p:inputText id="value2"
value="#{bean.value2}"
rendered="#{bean.value1 eq 18}"
>
</p:inputText>
</p:outputPanel>
</panel>
<div id="buttons">
<p:commandButton id="commandButton" action="#{bean.navigateAwayFromScreen}" value="Go away!" />
</div>
</layoutUnit>
</layout>
</form>
</html>
现在,对话在您打开页面时开始(由于从 beanOutput.xhtml 的顶部调用了 initConversation),并在您单击按钮 navigateAwayFromScreen 时结束。
(但是,如果您能够使用 JSF2.2,则应该可以将 @ViewScoped 与 CDI 结合使用。(我说 'should':我不适合升级.不过可能对别人检查有用)).