ui:repeat 中未触发 JSF 2.2 自定义验证器
JSF 2.2 custom validator not triggered in ui:repeat
经过一段绝望的尝试和错误时期后,我来找你寻求帮助,因为现在我什至不确定我是否做错了。
我下面的代码在只读输入文本框中显示用户配置文件中的一些字段。数据来自作为 "field" 对象的 ArrayList 的 bean,其属性在 ui:param 指令中进行了描述。
用户可以单击框旁边的 unlock/lock 按钮来 start/finish 编辑她的数据。
我想在用户编辑后按回车键或单击锁定按钮时触发输入验证。
但是无论我尝试过什么,在编辑并按下回车键或单击按钮后,更改的值都不会写回并且不会触发我的自定义验证器。不知何故,似乎在单击按钮后,然后呈现的输入框未绑定到该字段?但是,如果在始终呈现的输入文本中使用验证器(并且所有属性都传递给它),则验证器有效 - 我不明白它:)
请看一下。如果我没有很好地解释我的意图,或者您需要更多代码,请告诉我。
编辑:支持 bean 的注释:
@ManagedBean( name = "beanProfile" )
@RequestScoped
jsf代码:
<ui:composition>
<ui:param name="i18n" value="#{field.i18n}" />
<ui:param name="val" value="#{field.value}" />
<ui:param name="req" value="#{field.required}" />
<ui:param name="min" value="#{field.min}" />
<ui:param name="max" value="#{field.max}" />
<ui:param name="validationType" value="#{field.validationType}" />
<ui:param name="useHidden" value="#{field.hidden}" />
<ui:param name="locked" value="#{field.locked}" />
<ui:param name="fullName" value="#{beanProfile.name}" />
<h:form id="profileFrm">
<h:outputText value="#{msg.role_profile} " styleClass="headingOutputText" />
<h:outputText value="#{fullName}" styleClass="headerTitle" />
<p />
<h:panelGroup>
<ui:repeat var="field" value="#{beanProfile.userFields}">
<h:panelGrid columns="2">
<h:outputText value="#{msg[i18n]}" styleClass="headerTitle" />
<h:message showDetail="true" for="visInput" styleClass="warn"
rendered="#{!useHidden}" />
<h:message showDetail="true" for="invisInput" styleClass="warn"
rendered="#{useHidden}" />
</h:panelGrid>
<h:panelGrid columns="2" columnClasses="nameColumn">
<h:inputText id="visInput" required="true" value="#{val}"
rendered="#{!useHidden}" readonly="#{locked}" >
<f:validator validatorId="customValidator" />
<f:attribute name="requiredField" value="#{req}" />
<f:attribute name="minLen" value="#{min}" />
<f:attribute name="maxLen" value="#{max}" />
<f:attribute name="type" value="#{validationType}" />
</h:inputText>
<h:inputSecret id="invisInput" required="true" value="#{val}"
rendered="#{useHidden}" readonly="#{locked}">
<f:validator validatorId="customValidator" />
<f:attribute name="requiredField" value="#{req}" />
<f:attribute name="minLen" value="#{min}" />
<f:attribute name="maxLen" value="#{max}" />
<f:attribute name="type" value="#{validationType}" />
</h:inputSecret>
<h:commandLink id="lock" action="#{beanProfile.lock(field)}"
rendered="#{!locked}" title="#{msg.profile_lock}">
<h:graphicImage height="16" width="16"
name="images/padlock_unlocked.svg" alt="#{msg.profile_lock}" />
</h:commandLink>
<h:commandLink id="unlock" action="#{beanProfile.unlock(field)}"
rendered="#{locked}" title="#{msg.profile_unlock}">
<h:graphicImage height="16" width="16"
name="images/padlock_locked.svg" alt="#{msg.profile_unlock}" />
</h:commandLink>
</h:panelGrid>
</ui:repeat>
</h:panelGroup>
<p />
<h:commandButton id="submitProfileBtn" value="#{msg.cmd_submit}"
styleClass="button" includeViewParams="true"
action="#{beanProfile.submitProfile()}" />
</h:form>
</ui:composition>
谢谢 lametaweb,你指引了我正确的方向。
由于无法使用 @ViewScoped 注释,我找到了 link
并遵循 BalusC 在 Tomcat 中使用 CDI 的说明。然后我不得不让所有 java 类 实现 Serializable 接口。
现在我可以使用@ViewScoped 注释并触发验证器。
问题的根源是您正在为包含模型的支持 bean 使用 RequestScoped 范围,因此当您想要执行回发请求以执行支持 bean 方法时,绑定就消失了(不是在服务器内存中)并且 JSF 生命周期没有按预期执行。解决方案是使用更长的范围作为 ViewScoped 范围。理想情况下,您应该使用 CDI 兼容的 viewScoped 范围,因此您必须使用 JSF 2.2.x 版本。
经过一段绝望的尝试和错误时期后,我来找你寻求帮助,因为现在我什至不确定我是否做错了。
我下面的代码在只读输入文本框中显示用户配置文件中的一些字段。数据来自作为 "field" 对象的 ArrayList 的 bean,其属性在 ui:param 指令中进行了描述。 用户可以单击框旁边的 unlock/lock 按钮来 start/finish 编辑她的数据。 我想在用户编辑后按回车键或单击锁定按钮时触发输入验证。
但是无论我尝试过什么,在编辑并按下回车键或单击按钮后,更改的值都不会写回并且不会触发我的自定义验证器。不知何故,似乎在单击按钮后,然后呈现的输入框未绑定到该字段?但是,如果在始终呈现的输入文本中使用验证器(并且所有属性都传递给它),则验证器有效 - 我不明白它:)
请看一下。如果我没有很好地解释我的意图,或者您需要更多代码,请告诉我。
编辑:支持 bean 的注释:
@ManagedBean( name = "beanProfile" )
@RequestScoped
jsf代码:
<ui:composition>
<ui:param name="i18n" value="#{field.i18n}" />
<ui:param name="val" value="#{field.value}" />
<ui:param name="req" value="#{field.required}" />
<ui:param name="min" value="#{field.min}" />
<ui:param name="max" value="#{field.max}" />
<ui:param name="validationType" value="#{field.validationType}" />
<ui:param name="useHidden" value="#{field.hidden}" />
<ui:param name="locked" value="#{field.locked}" />
<ui:param name="fullName" value="#{beanProfile.name}" />
<h:form id="profileFrm">
<h:outputText value="#{msg.role_profile} " styleClass="headingOutputText" />
<h:outputText value="#{fullName}" styleClass="headerTitle" />
<p />
<h:panelGroup>
<ui:repeat var="field" value="#{beanProfile.userFields}">
<h:panelGrid columns="2">
<h:outputText value="#{msg[i18n]}" styleClass="headerTitle" />
<h:message showDetail="true" for="visInput" styleClass="warn"
rendered="#{!useHidden}" />
<h:message showDetail="true" for="invisInput" styleClass="warn"
rendered="#{useHidden}" />
</h:panelGrid>
<h:panelGrid columns="2" columnClasses="nameColumn">
<h:inputText id="visInput" required="true" value="#{val}"
rendered="#{!useHidden}" readonly="#{locked}" >
<f:validator validatorId="customValidator" />
<f:attribute name="requiredField" value="#{req}" />
<f:attribute name="minLen" value="#{min}" />
<f:attribute name="maxLen" value="#{max}" />
<f:attribute name="type" value="#{validationType}" />
</h:inputText>
<h:inputSecret id="invisInput" required="true" value="#{val}"
rendered="#{useHidden}" readonly="#{locked}">
<f:validator validatorId="customValidator" />
<f:attribute name="requiredField" value="#{req}" />
<f:attribute name="minLen" value="#{min}" />
<f:attribute name="maxLen" value="#{max}" />
<f:attribute name="type" value="#{validationType}" />
</h:inputSecret>
<h:commandLink id="lock" action="#{beanProfile.lock(field)}"
rendered="#{!locked}" title="#{msg.profile_lock}">
<h:graphicImage height="16" width="16"
name="images/padlock_unlocked.svg" alt="#{msg.profile_lock}" />
</h:commandLink>
<h:commandLink id="unlock" action="#{beanProfile.unlock(field)}"
rendered="#{locked}" title="#{msg.profile_unlock}">
<h:graphicImage height="16" width="16"
name="images/padlock_locked.svg" alt="#{msg.profile_unlock}" />
</h:commandLink>
</h:panelGrid>
</ui:repeat>
</h:panelGroup>
<p />
<h:commandButton id="submitProfileBtn" value="#{msg.cmd_submit}"
styleClass="button" includeViewParams="true"
action="#{beanProfile.submitProfile()}" />
</h:form>
</ui:composition>
谢谢 lametaweb,你指引了我正确的方向。
由于无法使用 @ViewScoped 注释,我找到了 link
并遵循 BalusC 在 Tomcat 中使用 CDI 的说明。然后我不得不让所有 java 类 实现 Serializable 接口。
现在我可以使用@ViewScoped 注释并触发验证器。
问题的根源是您正在为包含模型的支持 bean 使用 RequestScoped 范围,因此当您想要执行回发请求以执行支持 bean 方法时,绑定就消失了(不是在服务器内存中)并且 JSF 生命周期没有按预期执行。解决方案是使用更长的范围作为 ViewScoped 范围。理想情况下,您应该使用 CDI 兼容的 viewScoped 范围,因此您必须使用 JSF 2.2.x 版本。