我有以下xhtml、验证器和managedBean:
<h:form id="form">
<ui:repeat var="item" value="#{myBean.usersEmail}" varStatus="status">
<p:inputText id="userEmail" value="#{item.email}">
<f:validator validatorId="MyValidator"/>
</p:inputText>
<p:commandButton value="++++" update=":form" action="#{myBean.addEmail()}" />
</ui:repeat>
</h:form>
@FacesValidator("MyValidator")
public class ValidationClass extends Validator {
@Override
public void validate(FacesContext ctx, UIComponent component, Object value) throws ValidatorException {
String email = value.toString();
EmailValidator validator = EmailValidator.getInstance();
if(StringUtils.isNotBlank(email) && !validator.isValid(email)) {
FacesMessage message = new FacesMessage();
message.setSeverity(FacesMessage.SEVERITY_ERROR);
message.setSummary("Email is not valid.");
message.setDetail("Email is not valid.");
ctx.addMessage("userEmail", message);
throw new ValidatorException(message);
}
}
}
@ManagedBean
public class MyBean{
@Getter
@Setter
List<UserEmail> usersEmail = new ArrayList<UserEmail>();
public void addEmail(){
usersEmail.add(new UserEmail());
}
}
public class UserEmail{
@Getter
@Setter
String email = "";
}
在第一次验证失败之前,邮件添加一直有效。当这种情况发生时,所有的inputText组件都显示相同的值。例如,首先我添加"user1@gmail.com",这工作正常。然后我添加"user2@gmail.com",这也可以。然后我将"user1@gmail.com"更改为",这会抛出一个验证异常,该异常显示在屏幕上,一切仍然正常。但后来我用"user3@gmail.com"更正了"并提交,这次所有的inputText开始显示"user2@gmail.com",即使我添加了一个新的inputText,它也显示"user2@gmail.com"。
似乎当验证失败时,ui:repeat中的所有组件都绑定到最后一项的值。任何想法吗?
我改变了我的实现,使用JSTL中的c:forEach标签,现在它工作得很好,即使在Mojarra 2.2.6上,这就是我所做的:
<c:forEach var="item" items="#{myBean.usersEmail}" varStatus="status">
<p:inputText id="id${status.index}" value="${item.email}" validator="MyValidator" />
<p:message for="id${status.index}" />
<p:commandButton value="+" update=":form" action="#{myBean.addEmail()}" />
</c:forEach>