我正在学习JSF并需要一些帮助。我试图在页面中进行声明性验证,然而,呈现的必需消息在HTML标记中出现两次。
在我的托管bean中,我有一个students
字段,指向具有以下字段firstName
,otherNames
,surName
的学生实体。
这就是 Managed Bean 的样子:
@ViewScoped
public Class FormController implements Serializeble{
private List<Student> students = new ArrayList<>();
@PostConstruct
public void init(){
students.add(new Student());
students.add(new Student());
}
//getters and setters
}
然后在我的 JSF页面中,我有一个ui:repeat
指向我的bean中的students
,并在输入字段上进行声明性验证;
<h:form>
<table>
<ui:repeat value="#{formController.students}" var="student">
<tr>
<td><p:outputLabel value="first name:"/></td>
<td><p:inputText value="#{student.firstname}"
required="true"
requiredMessage="field cannot be blank"/></td>
<td><p:messages/></td>
</tr>
<!--other input fields omitted to make code cleaner-->
</ui:repeat>
</table>
<p:commandButton value="submit"
action="#{formController.saveStudents()}"/>
</h:form>
问题, 我面对的是,HTML标记中的每个输入字段都生成了两次所需的消息,如下所示:
<span class="bf-message">
<span class="bficon bficon-error-circle-o bf-message-icon" aria-hidden="true</span>
<span class="bf-message-detail">this feild cant be left blank</span></span><br /><span class="bf-message">
<span class="bficon bficon-error-circle-o bf-message-icon" aria-hidden="true"></span>
<span class="bf-message-detail">this feild cant be left blank</span></span>
//repeated likewise for all other input field required message,omitted to save space
这是我的发展环境
要添加更多细节,commandButtion操作指向的backing bean方法没有FacesMessages,实体类中的Field也没有验证注释。
答案 0 :(得分:2)
问题是您在<p:messages />
内嵌套了<ui:repeat>
。由于ui:repeat
会迭代您在渲染响应阶段添加到列表中的所有学生,因此最终会为您添加的每个学生添加一个消息组件。默认情况下,p:messages
组件会显示添加到FacesContext的所有消息(例如,所有验证消息)。
将<p:messages />
移出<ui:repeat>
,消息只会显示一次。
如果您希望在inputText
显示消息,则另一种解决方案是为inputText
组件提供id
属性并使用此id
属性在<p:messages />
中作为for
属性。当然,这个id
必须是唯一的。 for
属性使messages
组件仅显示为此特定组件添加的消息。但是,这不适用于<ui:repeat>
,因为ui:repeat
仅多次呈现组件,但实际上并未在组件树中创建多个组件。因此,您必须使用<c:forEach>
。请务必先阅读this introduction to JSTL tags in JSF。
<p:inputText id="#{student.id}" ... />
<p:messages for="#{student.id}" />