Primefaces:有条件渲染的组件未提交

时间:2015-07-22 11:10:36

标签: jsf jsf-2 rendered-attribute

我有一个基于下拉列表有条件呈现的字段。所有这一切都没有问题,但是当我提交新呈现的组件应该包含的表单时,它不会被提交。

代码非常简单:

<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>

尝试了可能的解决方案:

我可以想到导致这种行为的几种情况:

  1. 'Rendered'似乎根据辅助bean中的值重新评估, 而不是在UI中给出的新值(如果默认为1,则在提交时再次为1,而不是18)。因此,该组件 没有提交。
  2. 未正确添加添加的组件 表格,因此未提交。
  3. 选项1似乎是最有可能的选项,但任何人都可以指出我正确的方向吗?

    我使用WAS8.5(所以JSF2.0),Primefaces和CDI。

1 个答案:

答案 0 :(得分:0)

除了@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),并且当您单击navigationAwayFromScreen按钮时结束。

(但是,如果你能够使用JSF2.2,应该可以将@ViewScoped与CDI结合使用。(我说'应该':我不是在升级的情况。但它可能对其他人有用())。