在ui中导航组件树:重复

时间:2014-06-18 14:58:33

标签: jsf-2 primefaces

我们的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)

2 个答案:

答案 0 :(得分:2)

ui:repeath: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的一种方法是preValidateh: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将生成您需要的所有组件。

相关问题