我们的xhtml中有以下结构:
<ui:repeat ...>
...
<h:selectOneMenu ...>
...
<p:ajax event="change" update="@parent:@parent" process="@parent:@parent" />
</h:selectOneMenu>
</ui:repeat ...>
在事件处理程序中,我们可以访问代表selectOneMenu的UiComponent。我们可以导航到父,代表ui:repeat。看着孩子们,我希望看到网页上的所有selectOneMenu都可见,但我只看到一个单独的。触发变更事件的那个。
如何在ui:repeat组件之外访问兄弟组件?
动机:
我们基本上创建了一个分组表。即一个表,该表被分组为具有属于一起的数据的部分。上面的代码创建了一个组。必须为组中的一个条目选择selectOneMenu中的某些值。因此,当一个值发生更改时,我们必须访问同一组中的所有条目,以检查约束是否已满,并在违规字段上显示错误消息。
它在浏览器中的显示方式:
table: there is another outer repeat for creating the contents of this table
..group 1: content of each group is created by the ui:repeat
....row with selectOnMenu
....row with selectOnMenu
....row with selectOnMenu
....row with selectOnMenu
..group 2: content of each group is created by the ui:repeat
....row with selectOnMenu
....row with selectOnMenu
....row with selectOnMenu
....
使用selectOnMenu
行它在事件处理程序中的显示方式:
UiRepeat --> SelectOneMenu(exactly one)
答案 0 :(得分:2)
ui:repeat
和h:dataTable
等组件使用名为 stamping 的方法来处理子内容。这意味着子组件仅存在一次,无论value
中引用的集合中的项目数是多少。处理组件时,JSF会为集合中的每个项重用此组件(当您查看呈现的HTML时,您可以在ID中看到索引)。使用此方法,如果集合中有一个或1000个项目,则组件树的大小相同。
以上只是您注意到的行为的解释。关于您的问题,可能有多种解决方案,具体取决于具体要求和数据结构的方式。
您可以在触发请求的p:ajax
标记上指定的侦听器中进行验证(假设您可以查找模型中当前组的数据)。此侦听器在生命周期的第5阶段执行。如果ajax请求提交当前组,则数据应该已在模型中可用。
然后,您可以为特定组件添加验证错误消息,如下所示:
FacesContext ctx = FacesContext.getCurrentInstance();
ctx.addMessage("clientId of Component",
new FacesMessage(FacesMessage.SEVERITY_ERROR, "Your message", null));
获取已提交组件的clientID的一种方法是preValidate
上h:selectOneMenu
事件的系统事件监听器:
<f:event type="preValidate" listener="#{page.preValidate}"/>
在侦听器方法中,您可以访问当前组件的客户端ID(包括当前项的索引!):
public void preValidate(ComponentSystemEvent event) {
String clientId = event.getComponent().getClientId();
}
然后为所有提交的组件调用此侦听器。此外,您必须以某种方式将此clientId映射到模型中的当前项(例如,获取父ui:repeat
组件的索引)。
以上只是一些基本想法。
答案 1 :(得分:0)
根据您的行为和Micha的回答,您应该使用
<c:forEach>
而不是
<ui:repeat>
。 ForEach将生成您需要的所有组件。