验证器组件的属性值存在问题。 显然,首次访问页面时会创建验证器。
请参阅下面的代码:
<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”。 另外,我正在使用带有facelets的jsf1.2 ......
谢谢, 史蒂文
答案 0 :(得分:0)
多年来,我在非ajax环境中遇到过这个问题几次,今天再次点击它。添加Ajax并没有真正改变任何东西,因为一旦页面最初构建,ajax或其他方式,验证器属性永远不再被评估。
我提出的唯一解决方案是将validator属性设置为验证器表达式,然后在validate方法中评估该表达式。
我遇到的另一个问题(也包括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 Commons如何解决这个问题后,更好的解决方案是更改Facelets用于评估验证器和转换器属性表达式的规则。
它基本上归结为添加一个新的验证器或转换器MetaRule,当应用它时,检查属性值是否为非文字。如果它是非文字的,则在验证器或转换器上调用一个特殊方法,该方法传入值表达式而不是当前值。
此时的验证程序需要将值表达式存储为状态,并在需要时对其进行评估。 MyFaces公共提供了所有复杂的基础设施,以实现这一点,但您可以转储所有这些,并编写一个简单的自定义规则,并自己直接管理ValueExpression,类似于我最初发布的。