我使用com.sun.faces
版本2.1.18
。在我的申请中,我有一个动态的问题列表。我用<ui:repeat>
渲染每个问题。根据问题的类型,我呈现了输入组件和验证的类型。在数字范围问题的情况下,我使用<h:inputText>
和<f:validateLongRange>
。
我遇到的问题是,<f:validateLongRange>
上的minimum
和maximum
属性总是设置为第一个问题的最小和最大值。当你在其他问题上使用验证器时第一个问题就会失败。这是应该发生的吗?是否有一种方法可以对动态生成的组件进行验证?我希望不用切换到<c:forEach>
就能解决。
代码片段:
<ui:repeat value="#{questionnaire.questionsCollection}"
var="question">
..
<h:inputText value="..">
<f:validateLongRange minimum="#{question.minimumValue}"
maximum="#{question.maximumValue}"/>
</h:inputText>
..
</ui:repeat>
我已经输出了#{question.minimumValue}
和#{question.maximumValue}
,它们对我的问题有正确的值。
这确实是指定的/预期的行为。标记处理程序(如<f:validateXxx>
)的属性在视图构建时计算。所以他们不能引用一个只在视图渲染时可用的变量,比如<ui:repeat>
的当前迭代变量。当您使用像JSTL <c:forEach>
这样在视图构建期间运行的迭代器时,它确实可以工作。关于视图构建时间和视图渲染时间的更详细的解释在这里给出:JSF2 Facelets中的JSTL…有道理吗?
你基本上有相同的问题,在这里详细解释:如何设置转换器属性的每一行数据表?它详细概述了各种解决方案。在您的特殊情况下,解决方案之一是使用OmniFaces <o:validator>
,它支持对所有属性进行渲染时评估,因此您只需替换
<f:validateLongRange minimum="#{question.minimumValue}"
maximum="#{question.maximumValue}" />
<o:validator validatorId="javax.faces.LongRange"
minimum="#{question.minimumValue}"
maximum="#{question.maximumValue}" />
,以使其按预期工作。
参见:
- 基于ui使用EL设置验证器属性:repeat var