我有复合组件,其中有工具栏和数据表。我还定义了facet,其中包含一个用于从数据表中操作数据的表单。用户为不同类型的数据定义该方面。现在,我遇到了问题,因为我多次渲染该构面,现在我对 Primefaces components 的 widgetVar 名称有冲突。无法使用insertChildren多次,所以我认为这是唯一可能的解决方案。此外,我不想强迫组件的用户定义 10 个方面并编写 ui:include 10 次。有没有其他方法可以在复合组件中插入一些 facelet 代码,或者有没有办法将参数传递给 facet,并使用该参数动态创建 widgetVar?
3 回答
好的,一段时间后,我只是没有成功地做我想做的事。首先,我有一些这样的复合组件:
<cc:interface>
<!-- Attributes definition -->
<cc:facet name="form"/>
</cc:interface>
<cc:implementation>
<p:dialog><f:subview id="detailSubview1"><cc:renderFacet name="form"/></f:subview></p:dialog>
<p:dialog><f:subview id="detailSubview2"><cc:renderFacet name="form"/></f:subview></p:dialog>
<!-- There is some more renderFacets but this is enough -->
</cc:implementation>
例如,如果我p:selectOneMenu
在表单中没有任何widgetVar
定义,则所有名称都将具有相同的名称widgetVar
,这是一个问题。
所以,我完全改变了这一点,我将把这个复合组件转换为ui:composition
并在我的页面中装饰它。在这种情况下,小部件变量会根据我的需要生成,具有不同的名称,因为它们位于不同的命名容器中。
AwidgetVar
实际上在 JavaScript 中用于标识组件。因此 awidgetVar
在页面中必须是唯一的。你必须自己声明。
如果你想创建一个自定义组件,我认为可能比ui:define
/更适合你ui:include
,你可能想做这样的事情:
假设我们想要创建一个渲染 ap:commandButton
和 ah:outputText
具有相同值的组件(无论出于何种原因)。在目录中创建一个 XHTML 页面[deployed-root]/resources/example
,命名为customComponent.xhtm
:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsf/composite">
<c:interface>
<c:attribute name="text" required="true" />
</c:interface>
<c:implementation>
<h:outputText value="#{cc.attrs.text}" />
<p:commandButton value="#{cc.attrs.text}" />
</c:implementation>
</html>
然后要在另一个页面中使用它,您必须定义 namespace xmlns:e="http://java.sun.com/jsf/composite/example"
,然后您可以像这样引用自定义组件<e:customComponent text="some text here"/>
:
还应该注意的是,在自定义组件中声明表单是不好的做法。这会极大地影响使用的灵活性,因为表单不能嵌套。
PrimeFaces 可以生成wigetVar
s,因此您不必这样做。
从 3.4 用户指南:
<p:dialog id="dlg">
<!-- contents -->
</p:dialog>
<p:commandButton type="button" value="Show" onclick="#{p:widgetVar('dlg')}.show();"/>
这是为命名容器而设计的,所以它应该在复合组件中工作得很好<ui:repeat/>
,<h:dataTable/>
, 等。