2014-01-24 41 views
2

在JSF視圖上,我有一個<p:progressBar />,它顯示瞭如果初始化正確執行時的實際視圖。以下是實現的簡化版本:bean@ViewScoped受管bean,它是init()方法設置驗證器範圍(max)。正如你所看到的,如果<p:progressBar />完成後,它會更新main-container,然後把自己隱藏和顯示main-container:顯示main-containerAJAX:驗證器範圍未更新

<h:form id="loadingForm" prependId="false"> 

    <p:progressBar id="prog" widgetVar="pbAjax" ajax="true" interval="400" 
     value="#{progress.progressValue}" > 
     <p:ajax event="complete" 
      oncomplete="$('#prog').hide(); $('#main-container').show()" 
      update=":main-container" /> 
    </p:progressBar> 

    <p:remoteCommand autoRun="true" onstart="pbAjax.start();" 
     action="#{bean.init}" /> 
</h:form> 

<h:panelGroup layout="block" id="main-container" style="display: none;"> 

    <h:form id="formWithInputs" prependId="false"> 
     <p:growl id="messages" /> 

     <p:inputText id="maxA" value="#{bean.val}"> 
      <f:validateDoubleRange maximum="#{bean.max}" /> 
     </p:inputText> 

     <p:commandButton id="submitBtn" update="messages" /> 
    </h:form> 

</h:panelGroup> 

後,組件更新,並正確地呈現。然而,當我提交formWithInputs,我得到驗證錯誤,儘管能夠在輔助bean打印正確的價值max

maxA: Validation Error: Value is greater than allowable maximum of "0"

我有什麼改變,使驗證從使用更新後的值支持bean?

我使用MyFaces 2.1.14,PrimeFaces 4.0,GlassFish 3.1.2.2。

UPDATE - SSCCE:

Download Eclipse Project

測試上MyFaces 2.1.14PrimeFaces 4.0,GlassFish的3.1.2.2與鉻32 /火狐26.

XHTML

<!DOCTYPE html> 
<html lang="en" 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"> 
<h:head> 
</h:head> 

<h:body> 
    <h:form id="loadingForm" prependId="false"> 
     <p:progressBar id="prog" widgetVar="pbAjax" ajax="true" interval="400" 
      value="#{viewMBean.progress}" labelTemplate="{value}%"> 
      <p:ajax event="complete" 
       oncomplete="$(pbAjax.jqId).hide(); $('#main-container').show();" 
       update=":main-container" /> 
     </p:progressBar> 

     <p:remoteCommand autoRun="true" onstart="pbAjax.start();" 
      action="#{viewMBean.init}" /> 
    </h:form> 

    <h:panelGroup layout="block" id="main-container" style="display: none;"> 
     <h:form id="inputForm" prependId="false"> 
      <p:messages id="messages" /> 

      <p:inputText id="maxI" value="#{viewMBean.val}"> 
       <f:validateDoubleRange maximum="#{viewMBean.max}" /> 
      </p:inputText> 

      <p:commandButton id="submitBtn" value="SUBMIT" update="messages" 
       action="#{viewMBean.submit}" /> 

     </h:form> 
    </h:panelGroup> 

</h:body> 
</html> 

ViewMBean.java

@ViewScoped 
@ManagedBean 
public class ViewMBean implements Serializable { 

    private Integer max; 
    private Integer val; 

    private Integer progress; 

    public ViewMBean() { 
     this.max = 0; 
     this.val = 30; 

     this.progress = 0; 
    } 

    public Integer getMax() { 
     return max; 
    } 

    public void setMax(Integer max) { 
     this.max = max; 
    } 

    public Integer getVal() { 
     return val; 
    } 

    public void setVal(Integer val) { 
     this.val = val; 
    } 

    public Integer getProgress() { 
     return progress; 
    } 

    public void setProgress(Integer progress) { 
     this.progress = progress; 
    } 

    public void init() throws InterruptedException { 

     //simulates processing 
     setProgress(20); 
     Thread.sleep(1000); 
     setProgress(75); 
     Thread.sleep(1000); 

     //define maximum value 
     this.max = 100; 

     setProgress(100); 
    } 

    public void submit() { 
     Logger.getLogger(ViewMBean.class.toString()) 
      .log(Level.SEVERE, "Max: " + this.max + ", Val: " + this.val); 
    } 

} 

web.xml中:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    id="WebApp_ID" version="3.0"> 
    <display-name>Test</display-name> 

    <context-param> 
     <param-name>javax.faces.PROJECT_STAGE</param-name> 
     <param-value>Production<!-- Development --></param-value> 
    </context-param> 
    <context-param> 
     <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name> 
     <param-value>65536</param-value> <!-- 64KB. --> 
    </context-param> 
    <context-param> 
     <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name> 
     <param-value>-1</param-value> <!-- Should be -1 for production. --> 
    </context-param> 
    <context-param> 
     <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> 
     <param-value>true</param-value> 
    </context-param> 
    <context-param> 
     <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name> 
     <param-value>true</param-value> 
    </context-param> 
    <context-param> 
     <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
     <param-value>server</param-value> 
    </context-param> 

    <!-- MyFaces settings --> 

    <context-param> 
     <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name> 
     <param-value>false</param-value> 
    </context-param> 
    <context-param> 
     <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name> 
     <param-value>100</param-value> 
    </context-param> 

    <!-- Servlets and filters. --> 

    <welcome-file-list> 
     <welcome-file>bug.xhtml</welcome-file> 
    </welcome-file-list> 

    <servlet> 
     <servlet-name>Faces Servlet</servlet-name> 
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>Faces Servlet</servlet-name> 
     <url-pattern>*.xhtml</url-pattern> 
    </servlet-mapping> 
</web-app> 

OUTPUT:(點擊提交後)

maxI: Validation Error: Value is greater than allowable maximum of "0"

需要注意的是,如果我改變我的工作豆到@SessionScoped

回答

1

我無法找出確切原因,但給了OmniFaces嘗試。我將<f:validateDoubleRange />標籤轉換爲<o:validator />標籤。

<o:validator validatorId="javax.faces.DoubleRange" 
      maximum="#{viewMBean.max}" /> 

工程就像一個魅力。

另一個可行的解決方法是通過binding屬性使用驗證器,並直接從支持bean初始化它們。請參閱DoubleRangeValidator

標籤:

<f:validateDoubleRange binding="#{viewMBean.validator}" /> 

豆:

@ManagedBean 
@ViewScoped 
public class ViewMBean implements Serializable { 

    private DoubleRangeValidator validator; 

    public ViewMBean { 
     this.validator = new DoubleRangeValidator(20.0); 
    } 

    public void submit() { 
     Double max = 30.0; 
     this.validator.setMaximum(max); 

     Logger.getLogger(ViewMBean.class.toString()) 
       .log(Level.SEVERE, "Max: " + max); 
    } 

} 
+1

我能夠複製這個問題。當我從mojarra切換到myfaces時,它實際上只發生在我身上。 –

0

無法複製錯誤。如果有問題,我相信它會在你的@ManagedBean的某個地方。

下面是代碼,我對我所做的模擬你的問題:

<h:form id="loadingForm" prependId="false"> 
    <p:progressBar id="prog" widgetVar="pbAjax" ajax="true" interval="400" 
        value="#{viewMBean.progress}" > 
     <p:ajax event="complete" 
      oncomplete="console.log('a'); $(pbAjax.jqId).hide(); $('#main-container').show()" 
      update=":main-container" /> 
    </p:progressBar> 
    <p:remoteCommand autoRun="true" onstart="pbAjax.start();" 
        action="#{viewMBean.init}" /> 
</h:form> 

<h:panelGroup layout="block" id="main-container" style="display: none;"> 
    <h:form id="formWithInputs" prependId="false"> 
     <p:messages id="messages" /> 
     <p:inputText id="maxA" value="#{viewMBean.val}"> 
      <f:validateDoubleRange maximum="#{viewMBean.max}" /> 
     </p:inputText> 
     <p:commandButton id="submitBtn" value="Validate" /> 
    </h:form> 
</h:panelGroup> 

@ManagedBean

import java.io.Serializable; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 

@ManagedBean 
@ViewScoped 
public class ViewMBean implements Serializable { 

    private Integer progress = 0; 

    private Integer max = 0; 

    private Integer val = 0; 

    public Integer getProgress() { 
     return progress; 
    } 

    public void setProgress(Integer progress) { 
     this.progress = progress; 
    } 

    public Integer getMax() { 
     return max; 
    } 

    public void setMax(Integer max) { 
     this.max = max; 
    } 

    public Integer getVal() { 
     return val; 
    } 

    public void setVal(Integer val) { 
     this.val = val; 
    } 

    public void init() throws InterruptedException { 
     //simulates processing 
     progress = 50; 
     Thread.sleep(2000); 
     progress = 75; 
     Thread.sleep(2000); 
     progress = 100; 
     //define maximum value 
     max = 100; 
    } 

} 
+0

什麼是適合你的結局?我想你提交時沒有任何反應。我的問題中的代碼是一種假的,對此很抱歉。嘗試將''更改爲'',並用''將其更新。我已經相應地更改了問題中的代碼。 –

+0

它按預期工作。當進度條結束時,輸入顯示,並且maxvalue從0更新到100.當我輸入101時,出現驗證錯誤。以下任何數字都可以提交。 –

+0

我編輯了這個問題,並添加了我的項目中的確切來源。 –