首先,让我解释一下结构。我有一些 JSF Facelets 页面,它们使用模板来提供带有动态生成菜单的通用标题。在该模板中,使用以下代码生成菜单:
<ui:repeat var="item" value="#{mainMenuBackingBean.subMenuItemsList}">
<td class="#{item.cssClass}">
<h:outputLink id="submenu_#{item.nameText}" value="#{item.linkPath}" disabled="#{item.disabled}">
#{item.nameText}
</h:outputLink>
</td>
</ui:repeat>
每个单独的页面都有一个页面支持 bean,它知道如何设置其菜单,因此在呈现页面之前,使用以下代码设置菜单:
<f:event listener="#{specificPageBackingBeanHere.setup}" type="preRenderView"></f:event>
它调用所有特定页面支持 bean 扩展的抽象类中的 setup 方法,然后进行一些调用以将正确的元素添加到 mainMenueBackingBean 的菜单列表。到目前为止,这对我们来说非常完美,直到现在我们还没有遇到任何问题。
在一个新页面上,我们有一个动态布局的表格,使用以下代码实现:
<table class="gridall">
<tr>
<td colspan="4" style="text-align: center;"><b>Table Title</td>
</tr>
<tr>
...
column headings here
...
</tr>
<ui:repeat var="item" value="#{outgoingFaxBacking.outgoingList}">
<tr bgcolor="#{item.status.color}">
<td style="text-align: center;" class="itemsTopCell">
<h:commandLink value="#{item.itemNo}" action="#{outgoingFaxBacking.testMe}" >
<f:ajax render=":rightColumn"/>
</h:commandLink>
<br/>
<b>Last: #{item.lastString}</b>
</td>
<td class="itemsTopCell">
#{item.description}
</td>
<td style="text-align: center" class="itemsTopCell">
<h:outputText value="#{item.quantity}">
<f:convertNumber maxFractionDigits="2"/>
</h:outputText>
</td>
<td style="text-align: center;" class="itemsTopCell">
<h:inputHidden id="notFilledNote" value="#{outgoingFaxBacking.notFilledNote}"/>
<h:commandButton action="#{outgoingFaxBacking.markNotFilled(item.id)}" onclick="return(notFilled());" value="Not Filled">
<f:ajax execute="notFilledNote" render="@form"/>
</h:commandButton>
</td>
</tr>
<tr bgcolor="#{item.status.color}">
<h:panelGroup rendered="#{empty item.note}">
<td style="border-top: 1px;" colspan="4">
#{item.sig}
</td>
</h:panelGroup>
<h:panelGroup rendered="#{not empty item.note}">
<td style="border-top: 1px; border-bottom:0px;" colspan="4">
#{item.sig}
</td>
</h:panelGroup>
</tr>
<h:panelGroup rendered="#{not empty item.note}">
<tr bgcolor="#{item.status.color}">
<td colspan="4" style="border-top: 1px;">
#{item.note}
</td>
</tr>
</h:panelGroup>
<tr>
<td style="border: 0px;font-size:2%" colspan="3">
</td>
</tr>
</ui:repeat>
</table>
页面第一次完美呈现。问题是,当您单击表中的 commandLink 或 commandButton 时(并且只有此表,页面上没有其他命令元素会导致此问题),会生成一个错误,如下所示:
serverError:类 javax.faces.view.facelets.TagAttributeException /WEB-INF/templates/secure.xhtml @130,106 id="submenu_#{item.nameText}":在 org.ppa.db 类型上找不到属性“nameText”。 serializabledb.FaxItemsContainer
错误位置 (@130,106) 是我在上面引用的菜单代码,但正在查看的对象类型 (FaxItemsContainer) 在上面的动态表中使用,而不是菜单。在摆弄了一会儿之后,确保它不是 ajax 问题、ui:include 问题或其他任何问题,我们最终将表中的 var 名称从“item”更改为“faxItem”,它出现了去工作。
所以最终,我的问题是我认为 ui:repeat (和其他 JSF 组件)的 var 名称在范围内是本地的,因此同一页面上的两个 ui:repeat 使用相同的 var 名称并不重要;不是这样吗?同一页面上的 ui:repeat 标签真的需要唯一的 var 名称吗?
我在 Tomcat 7 上运行 Mojarra 2.1.3。