2010-12-14 57 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,类似于我最初发布的内容。