繁体   English   中英

JSF FacesMessage 只显示一次,但应该在每次错误发生时显示

[英]JSF FacesMessage shown only once, but is supposed to be shown each time the error occurs

我正在使用 JSF 2.3 (Mojarra 2.3.9.SP02) 和 PrimeFaces 7.0 在 WildFly 17 (Ubuntu 18.04 TLS / or Windows 10) 上运行。 在我的支持 bean(它是一个 ViewScoped)中的操作方法weiterBid()中,我检查用户是否刚刚选中了一个复选框。 如果不是,则错误消息会在组件<p:panel id="errorMsgPanelId"中显示为红色(请参阅下面的 facelet),并且用户会停留在同一页面上。 每次用户单击“下一步”按钮时都会执行此检查。

现在,我的理解是,即使用户关闭错误消息面板,每次他/她单击“下一步”按钮时,都会调用操作方法,并再次检查用户是否选中了复选框然后再次。 如果未选中该复选框,则错误消息应再次显示在与之前相同的<p:panel id="errorMsgPanelId">组件中。 这真的是应该的行为吗? 如果是,那么我有一个错误,即错误消息仅在第一次单击“下一步”按钮时显示,并且一旦用户关闭显示它的面板就再也不会显示。

github 上的最小工作示例项目:

https://github.com/alexmivonwien/pf.error.msg

我的支持豆:

    @Named("aveBidUnterlagenBean")
    @javax.faces.view.ViewScoped
    public class AveBidUnterlagenBean implements Serializable {

        private boolean confirmationDocumentsGiven;

        private FacesMessage errorMessageOnDocumentConfirmation;

        public boolean isConfirmationDocumentsGiven() {
            return confirmationDocumentsGiven;
        }

        public void setConfirmationDocumentsGiven(boolean confirmationDocumentsGiven) {
            this.confirmationDocumentsGiven = confirmationDocumentsGiven;

        }

        public String weiterBid() {
            if (!confirmationDocumentsGiven) {
                String errorMessage = "Please confirm documents for the real estate";

                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMessage, null);
                FacesContext.getCurrentInstance().addMessage(null, message);
                this.errorMessageOnDocumentConfirmation = message;
                return null;
            }

            return null;
        }   

        public FacesMessage getErrorMessageOnDocumentConfirmation() {
            return errorMessageOnDocumentConfirmation;
        }

        public void onCloseErrorMsgPanel(CloseEvent event) {
            this.errorMessageOnDocumentConfirmation = null;
        }
    }

在 facelet 中我有组件

    <!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
<h:head>
    <meta charset="UTF-8"/> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</h:head>
        <h:outputStylesheet name="primeicons/primeicons.css" library="primefaces"/>
        <h:form id="persDatenForm">  
                <p:panel id="errorMsgPanelId" styleClass="errorMsgPanel" closable="true" widgetVar="errorMsgPanel" rendered="#{aveBidUnterlagenBean.getErrorMessageOnDocumentConfirmation()!=null}">
                   <p:ajax event="close" listener="#{aveBidUnterlagenBean.onCloseErrorMsgPanel}" update="@parent" />
                   <h:outputText style="color:red;" value="#{aveBidUnterlagenBean.errorMessageOnDocumentConfirmation.detail}"/>
                   <p:commandLink outcome="#" style="background-color:white;" onclick="PF('errorMsgPanel').close()">
                        <i class="pi pi-times"></i>
                   </p:commandLink>
                </p:panel>
                <br/>
                <p:outputLabel value="Documents overwiev"/>
                <br/>
                <br/>
                <p:selectBooleanCheckbox value="#{aveBidUnterlagenBean.confirmationDocumentsGiven}" itemLabel="I confirm that I read the documents"/>
                <br/>
                <br/>
                <p:commandButton  icon = "pi pi-check" value="Next" action="#{aveBidUnterlagenBean.weiterBid}" update="@form"/>
         </h:form>  
</html>

现在,我的问题是,如果我没有选中复选框,而是第一次单击“下一步”按钮,则会调用操作方法并显示错误消息。 如果我关闭错误消息面板,然后再次单击同一个“下一步”按钮,而没有选中该复选框,错误消息将永远不会再次显示。

这是错误还是功能? 我怎样才能克服它?

谢谢你和亲切的问候:亚历克斯

更新在操作之后执行。 相反,使用 actionListener:

<p:commandButton  icon = "pi pi-check" value="Next" actionListener="#{aveBidUnterlagenBean.weiterBid}" update="@form"/>

update 在 actionListener 之后但在 action 之前调用,我认为因为视图已经刷新。 所以你的 bean confirmationDocumentsGiven 是假的,但它永远不会更新到正确的 FacesContext。

(我没有测试这个)

好的,我认为问题是

rendered="#{aveBidUnterlagenBean.getErrorMessageOnDocumentConfirmation()!=null}". 

在您的 onCloseErrorMsgPanel 中,您将该错误消息设置为 null。

第一次访问:有效,设置了错误消息,关闭对话框 -> 错误消息为 null,更新@parent -> 面板呈现=false,然后调用操作 -> 服务器端所有值都正确,但是

第二次访问:update="@form" 或 generaly ajax 更新将跳过所有具有 rendered=false 的组件

该怎么办? 使用设置 errormsg =/= PlaceHolder.NotNull 的操作,然后调用更新,加载面板(渲染 = true,因为 errormsg =/= null),而不是使用设置 errormsg = actualValue 的 actionlistener。

这样,面板应该更新并包含在您的 DOM 中。

这是解决方法,希望它能解决您的问题。
<p:panel id="errorMsgPanelId" styleClass="errorMsgPanel" closable="true" widgetVar="errorMsgPanel">
<p:outputPanel id="wrapper" rendered="#{aveBidUnterlagenBean.getErrorMessageOnDocumentConfirmation() != null}">
<h:outputText style="color:red;" value="#{aveBidUnterlagenBean.errorMessageOnDocumentConfirmation.detail}"/>
<p:commandLink style="background-color:white;" actionListener="#{aveBidUnterlagenBean.onCloseErrorMsgPanel}" update="@form" process="@this">
<i class="pi pi-times"/>
</p:commandLink>
</p:outputPanel>
</p:panel>

并将支持 bean 方法更改为以下内容:
public void onCloseErrorMsgPanel() { this.errorMessageOnDocumentConfirmation = null; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM