我在一個非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,類似於我最初發布的內容。
這將有助於如果你標記'mw'。我不知道那是什麼。這是一個自定義組件嗎? – 2010-12-14 14:01:20
是的,這是一個自定義驗證器。雖然沒有特別的,但只有2個雙重成員變量,都有一個getter和一個setter。 問題是,基本上只有在頁面建立時纔會調用getters。所以在重新渲染時,組件樹就存在了,驗證器的設置者不會被調用。因此,我的驗證器中有不正確的值,我想以某種方式解決這個問題...(沒有測試,但我相信你會得到與f:valiateLongRange標籤相同的結果) – 2010-12-14 14:46:33