【问题标题】:Is there a way to not sending a whole web form when click a button?有没有办法在单击按钮时不发送整个 Web 表单?
【发布时间】:2011-04-03 09:25:49
【问题描述】:

我会尽量简短,请留在我这里

"A.jsf" -> 托管 bean : bean “#{bean.list}”:将带我们到 B.jsf

        <p:growl id="msgs" showDetail="true"/>
        <h:form id="myform1" enctype="multipart/form-data">
            <p:panel header="Upload" style="font-size: 11px;">
                <h:panelGrid columns="2" cellpadding="10">
                    <h:outputLabel value="Drawing:" />
                    <p:fileUpload fileUploadListener="#{bean.handleFileUpload}" update="msgs" allowTypes="*.*;"/>                        
                </h:panelGrid>
                <p:commandButton ajax="false" immediate="true" id="back" value="Back" action="#{bean.list}"/>
                <p:commandButton ajax="false" id="persist" value="Persist" action="#{bean.handleRevision}" />
            </p:panel>
        </h:form>

然后handleFileUpload()

        if(!upload){
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "You do not have permission to upload.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
        ...

"B.jsf" -> 托管 bean:bean2

 ...
 <p:growl id="msgs" showDetail="true"/>
 ...

当我点击上传时,它给我一个咆哮的错误消息“你没有上传权限。”,这很好。但是当我单击“返回”时,我将转到 B.jsf,我看到了咆哮消息“您没有上传权限”。再次。似乎正在发生的事情是当我单击“返回”时,我发送其他表单请求上传,然后生成相同的错误消息,然后显示在 B.jsf 中。有没有办法解决这个问题,除了将“返回”按钮放入一个空表单之外,因为现在我有两个按钮彼此叠放,而不是并排。我尝试这样做:

FacesContext.getCurrentInstance().addMessage("tom", msg);

希望它会发送到 id="tom" 的组件,因此 id=msgs 的咆哮不会被加载,但没有运气。当我单击Back 按钮时,我尝试打开upload 标志,但是在调用处理back 导航的方法之前请求了Web 表单。

它没有我想要的那么简短,因此我想为此道歉:D

【问题讨论】:

    标签: java jsf primefaces


    【解决方案1】:

    除了将“返回”按钮放入一个空表单之外,因为现在我有两个按钮相互叠放

    HTML &lt;form&gt; 默认为block element。默认情况下,HTML 块元素被放置在新行中。您实际上想将其设为inline element。您可以在 CSS 中使用 display: inline; 来做到这一点。

    回到实际问题,尽管p:commandButton 中有immediate="true",但仍调用fileUploadListener 方法让我感到惊讶。我试图重现这一点,我可以确认这一点。但我不希望它发生。 通常按钮上的immediate="true"跳过提交“整个”表单的解决方案(至少,跳过没有此属性的UIInput 组件)。进一步的调查了解到p:fileUpload 根本不是UIInput 组件,并且侦听器在应用请求值阶段而不是验证或更新模型值阶段被触发。所以这种行为是完全可以预测的,但 imo 仍然是设计中的疏忽。

    由于p:fileUpload 需要p:commandButton 组件上的ajax="false",另一方面,您也可以将其从后退按钮中删除,以便它触发一个ajaxical 请求,从而跳过正在调用的fileUploadListener

    【讨论】:

    • Back 按钮的p:commandButton 上取出ajax="false" 确实可以防止fileUploadListener 被调用,但也可以防止navigation flow。结果,Back 按钮让我无处可去,但是,display:inline 效果很好,非常感谢您花时间在上面,BalusC
    【解决方案2】:

    实际上,将按钮设置为不同的形式听起来是一个很好的解决方案。按钮不再对齐的原因是新的起始&lt;form&gt; 元素从它自己的行开始。您应该能够通过将form { display: inline; } 添加到您的 CSS 文件来防止这种情况发生。

    也就是说,如果您想删除一些剩余的错误消息,您可以在支持 bean 的初始化方法中执行此操作(如果有的话)。以下内容非常有效:

    public void clearErrorMessages() {
        //it may get messy to debug why messages are swallowed
        logger.debug("clearing messages, coming from " + new Exception().getStackTrace()[1]);
    
        Iterator iter = FacesContext.getCurrentInstance().getMessages();
        while (iter.hasNext()) {
            FacesMessage msg = (FacesMessage) iter.next();
            logger.debug("clearing message: " + msg.getDetail());
            iter.remove();
        }
    }
    

    这里的缺点是提交表单和初始化目标页面的backing bean之间发生的任何错误也会被吞掉。

    【讨论】:

    • 谢谢。我试试这个&lt;h:form style="margin:0;"&gt;Submit Button &lt;/h:form&gt; &lt;h:form&gt; Back Button &lt;/h:form&gt;,我还有两个站在一起的。方法clearErrorMessages(),你说把它放到目标托管bean的初始化方法中,好吧我的目标托管bean有SessionScoped,所以构造函数只会在应用程序第一次加载时调用一次,除非有某种用于检测页面何时重新加载的注释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 2012-05-11
    • 2021-06-08
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    相关资源
    最近更新 更多