我有一个复合组件,它捆绑了一些输入字段。该组件将在页面上多次使用,并包含一个用于复制其他组件的值的按钮。为此,我需要通过其clientId访问其中一个兄弟姐妹作为
的目标 <f:ajax execute=":XXX:siblingId" render="...">
我的问题在于构建此ID。我有兄弟的名字,我可以确保它与包含复制按钮的组件位于相同的命名容器中,但我无法控制完整的嵌套层次结构,因此它可能是:form:foo:bar:parent:child
或只是form:parent:child
。所以基本上我想获得当前复合组件的前缀,但没有组件自己的ID,然后附加要复制的组件的ID。
这与以下问题类似:
但是,这两个答案都使用了PrimeFaces特殊功能,例如@parent
和widgetVar
,这些功能不适用于我的项目。
在尝试使用EL的隐式对象时,我基本上尝试了与第二个问题的海报相同的内容 - 结果相同:cc.parent.clientId
始终为空。我也试过cc.namingContainer.clientId
和两者的一些组合,唉 - 没有成功。特别是parent
无法正常工作的事实让我感到困惑......
那么:是否存在与组件库无关的方式来访问包含复合组件命名容器的“路径”? parent
对象应该如何工作,尤其是:我们什么时候可以使用它?什么时候不能使用它?
PS:我正在考虑使用复合的完整clientId,然后使用fn:split
修剪其实际ID,但是,如果有更直接的方式,我会乐意使用它。
答案 0 :(得分:6)
#{cc.parent}
解析为UIComponent#getCompositeComponentParent()
,返回最近的父复合组件。换句话说,当复合组件本身嵌套在另一个复合组件中时,它仅返回非null
。
#{cc.namingContainer}
只是引用#{cc}
本身,完全符合UIComponent#getNamingContainer()
中的规定:
从“this”开始,如果找不到,则返回祖先中最近的
NamingContainer
或null
组件。
复合组件即隐式实现NamingContainer
。
所以不幸的是,你的尝试无效。我也没有看到任何“标准API”方法来实现具体的功能要求。 CompositeComponentAttributesELResolver
导致#{cc.parent}
未解析为UIComponent#getParent()
,这是您最终想要的。
但是,您可以为复合提供自定义UIComponent
实施,该实施会添加一个带有唯一名称的额外getter,该名称又会正确委托给UIComponent#getParent()
。
这是一个启动示例:
@FacesComponent("myComposite")
public class MyComposite extends UINamingContainer {
public UIComponent getParentComponent() {
return super.getParent();
}
}
如果在复合界面中按如下方式注册:
<cc:interface componentType="myComposite">
然后你就可以使用
了#{cc.parentComponent.clientId}
获取真实父UIComponent
的客户端ID。
最终你应该能够使用以下构造来引用兄弟:
process=":#{cc.parentComponent.clientId}:siblingId"