2010-12-14 52 views
0

我遇到驗證程序組件屬性值的問題。 顯然,我第一次訪問頁面時創建了驗證程序。重新刷新JSF驗證程序屬性

請參閱下面我的代碼:

<h:inputText value="#{qsetting.value}" rendered="#{qsetting.dataType=='Double'}"> 
    <mw:validateRange min="#{qsetting.minValue}" max="#{qsetting.maxValue}" /> 
</h:inputText> 

inputText組件是通過Ajax重新呈現,但顯然,其中所顯示的值。 不幸的是,qsetting.minValue和qsetting.maxValue沒有刷新,導致我的驗證器無法正常工作。

是否有可能刷新驗證程序,以確保它重新檢索其屬性或僅創建驗證程序的新實例? 驗證器類本身當前正在實現「Validator,Serializable」。 另外,我使用JSF1.2與小面...

感謝, 史蒂芬

+0

這將有助於如果你標記'mw'。我不知道那是什麼。這是一個自定義組件嗎? – 2010-12-14 14:01:20

+0

是的,這是一個自定義驗證器。雖然沒有特別的,但只有2個雙重成員變量,都有一個getter和一個setter。 問題是,基本上只有在頁面建立時纔會調用getters。所以在重新渲染時,組件樹就存在了,驗證器的設置者不會被調用。因此,我的驗證器中有不正確的值,我想以某種方式解決這個問題...(沒有測試,但我相信你會得到與f:valiateLongRange標籤相同的結果) – 2010-12-14 14:46:33

回答

0

我在一個非Ajax環境打到這個問題多年來幾次,並再次打今天。 Ajax的添加並不會真正改變任何事情,因爲一旦頁面最初構建,ajax或其他方式,驗證器屬性就不會再次被評估。

我想出的唯一解決方案是將驗證器屬性設置爲驗證器表達式,然後在驗證方法內評估該表達式。

我碰到的另一個問題(也是JSF 1.2和Facelets)並不是所有的EL變量都起作用。我不得不使用靜態託管bean作爲我的表達式的根目錄來訪問該值。作爲根的facelet ui:param值不起作用。我還沒有測試過,看看還有什麼可能無法正確評估。這可能是由於JSF本身設計中的另一個缺陷。請參閱http://myfaces.apache.org/core12/myfaces-api/apidocs/javax/faces/context/FacesContext.html#getELContext%28%29

,而不是例如:

max="#{qsetting.maxValue}" 

使用

maxExpression="qsetting.maxValue" 

然後

public String getMax(FacesContext context) { 
    Application app = context.getApplication(); 
    ExpressionFactory exprFactory = app.getExpressionFactory(); 
    ValueExpression ve = exprFactory.createValueExpression(context.getELContext(), 
      "#{" + getMaxExpression() + "}", 
      String.class); 

    Object result = ve.getValue(context.getELContext()); 

    return (String)result; 
} 

public String getMaxExpression() { 
    return this.maxExpression; 
} 

public void setMaxExpression(String maxExpression) { 
    this.maxExpression = maxExpression; 
} 


//// StateHolder 

public boolean isTransient() { 
    return isTransient; 
} 

public void setTransient(boolean newTransientValue) { 
    isTransient = newTransientValue; 
} 

public Object saveState(FacesContext context) { 
    Object[] state = new Object[1]; 
    state[0] = maxExpression; 
    return state; 
} 

public void restoreState(FacesContext context, Object state) { 
    Object[] values = (Object[]) state; 
    maxExpression = (String) values[0]; 
} 

更新2012-09-19:

研究如何MyFaces的共享解決了之後這個問題,更好的解決方案是更改Facelets用來評估驗證器和轉換器屬性表達式的規則。

它基本上歸結爲添加一個新的驗證器或轉換器MetaRule,應用時檢查屬性值是否爲非文字。如果它不是文字,請在您的驗證器或轉換器上調用一個特殊方法,該方法將傳入值表達式而不是當前值。

http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-validators/src/main/java/org/apache/myfaces/commons/validator/_ValidatorRule.java?view=markup

在該點的驗證程序需要存儲的值表達狀態並在需要時對其進行評估。 MyFaces commons提供了所有複雜的基礎設施,以使這種情況一般發生,但您可以轉儲所有這些,並編寫一個簡單的自定義規則,並自己直接管理ValueExpression,類似於我最初發布的內容。