我的应用程序中有许多复合组件,有时我需要引用这些组件作为一个整体。默认情况下,复合组件不会在其子组件上生成任何其他标记,因此,如果为复合组件提供id属性,则只需将该id附加到子组件的生成ID即可。我想通过id引用整个组件(即用于jquery操作)。 JSF组件不允许在id属性中使用EL,所以为了实现这一点,我到目前为止将我的复合组件包装在普通的html div中,如下所示:
<ui:component ...
xmlns:cc="http://java.sun.com/jsf/composite"
...>
<cc:interface componentType="myComponent">
<cc:attribute name="process" type="java.lang.String" required="false" default="@form"/>
<cc:attribute name="update" type="java.lang.String" required="false" default="@form"/>
...
</cc:interface>
<cc:implementation>
<h:outputStylesheet name="myComponent.css" library="css/components" target="head"/>
<div id="#{cc.clientId}" class="myComponent #{cc.attrs.styleClass}">
... composite component implementation here ...
<p:dataTable id="note-history" styleClass="entity-notes-history" value="#{cc.notes}" var="note" paginator="true" paginatorAlwaysVisible="false"
paginatorPosition="bottom" rows="5" rendered="#{not empty cc.notes}" rowStyleClass="#{note.noteBaseType.word}">
...
<p:column rendered="#{note.noteBaseType == 'Warning' and not cc.attrs.displayOnly}" style="width: 8em;">
<p:commandButton actionListener="#{cc.cancelSeverity(note.id)}" process="#{cc.attrs.process}" update="#{cc.attrs.update} update="note-history" value="Reduce Severity"/>
</p:column>
</p:dataTable>
</div>
</cc:implementation>
该组件将按如下方式使用:
....
<ppa:myComponent id="myId" update="myId" />
....
不幸的是,如果我在复合组件中有任何ajax(特别是来自primefaces的p:ajax)调用,当我尝试让它们通过ID更新复合组件时,我得到一个&#34;找不到具有标识符&#34的组件;例外。有没有办法让JSF为我的复合组件自动生成有效的组件和容器?我真的不想生成两个包含div或spans(即在简单的html div周围添加一个h:panelGroup)只是为了让ajax工作。或者,有没有办法强制JSF允许组件上的动态ID?
在回答BallusC的回答时,我已经编辑了示例代码,以便更清楚地了解组件的构建和使用方式,因为根据他的回答,我完全可以使用它。我正在做一些不允许的事情。
答案 0 :(得分:2)
当我尝试让他们通过ID更新复合组件时,我得到一个&#34;找不到具有标识符&#34的组件;例外
很遗憾你没有表明你是如何做到这一点的,因为如果你在更新中使用了复合的客户端ID,它应该可以正常工作。复合本身:
<f:ajax render=":#{cc.clientId}" />
或者,您刚刚在更新中使用了复合自己的ID,该ID在同一命名容器父级内的复合外部执行:
<f:ajax render="myId" />
你最有可能以错误的方式做到了。例如。您忘记了:
前缀,或者您使用了#{cc.id}
而不是#{cc.clientId}
等。据我所知,上述内容始终适用于目前发布的所有Mojarra 2.x版本。< / p>
或者,是否有办法强制JSF允许组件上的动态ID?
您可以在id
属性中使用EL,前提是它在视图构建期间可用,因此不仅在视图渲染时间内。有关相关背景信息,另请参阅JSTL in JSF2 Facelets... makes sense?。
更新,其中您最终会展示您是如何尝试实现的;
使用
<ppa:myComponent id="myId" update="myId" />
和
<p:commandButton ... update="#{cc.attrs.update}" />
你有效地最终做了
<p:commandButton ... update="myId" />
基本上是在复合材料本身的上下文中寻找ID为myId
的组件!它只对例如同一<h:outputText id="myID">
内的<p:commandButton>
旁边的<cc:implementation>
。
理解功能要求,但解决方案并不是那么好。您最接近的赌注是(ab)使用@this
并在update
中有条件地检查{<1}}:
<ppa:myComponent id="myId" update="@this" />
有这样的东西
<p:commandButton ... update="#{cc.attrs.update == '@this' ? ':'.concat(cc.clientId) : cc.attrs.update}" />