【问题标题】:Primefaces: conditionally rendered component doesn't get submittedPrimefaces:有条件渲染的组件没有被提交
【发布时间】:2015-10-12 05:30:03
【问题描述】:

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

代码相当简单:

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

【问题讨论】:

  • “因为它与 CDI 冲突” 嗯?换句话说,您还没有使用 JSF 2.2 并且无法升级? JSF 2.2 具有与 CDI 兼容的 @ViewScoped 注释。
  • 描述 UI 应该如何工作、您在 UI 中所做的事情以及您的期望在什么时候失败。目前尚不清楚您的 rendered 绑定应该完成什么。
  • @VsevolodGolovanov:OP 的案例失败,因为他的 bean 是请求范围而不是视图范围。现在,OP 基本上是在询问如何维护视图范围状态而不使 bean 视图范围。 “少数场景”列表毫无意义。它已经解释了很长时间,特别是 OP 提到的第二个链接(因此,只要 OP 没有详细说明他对@ViewScoped 的具体问题,这基本上是当前形式的问题的副本)
  • 我们正在使用 WAS8.5,因此使用的是 JSF2.0。我不确定是否可以升级到 2.2,所以我正在寻找另一种解决方案。使用@Viewscoped 时,AJAX 组件的更改会导致类似javax.faces.FacesException: Exception while validating component with path ... 的错误,或者这不相关?
  • 为什么在实际使用 WAS 8.5(不是 Java EE 7)时,最初用(不必要的)[java-ee-7] 标签标记问题?您是通过 JSF @ManagedBean 还是 CDI @Named 管理 bean?有了那个“冲突”,你实际上意味着你特别面临那个例外吗? (在保留@ViewScoped btw 的同时,这确实可能相关且可以回答)该异常与“与 CDI 冲突”究竟有何关系?

标签: jsf jsf-2 rendered-attribute


【解决方案1】:

在@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 结合使用。(我说“应该”:我不适合升级。但它可能对别人有用))。

【讨论】:

    猜你喜欢
    • 2017-10-12
    • 2017-06-11
    • 1970-01-01
    • 2017-04-15
    • 2018-05-19
    • 2020-01-22
    相关资源
    最近更新 更多