如何通过clientId访问复合组件的兄弟

Lou*_*ise 3 jsf clientid naming-containers composite-component

我有一个复合组件捆绑一些输入字段.该组件将在页面上多次使用,并包含一个用于复制其他组件的值的按钮.为此,我需要通过其clientId访问其中一个兄弟姐妹作为目标

<f:ajax execute=":XXX:siblingId" render="...">

我的问题在于构建此ID.我有兄弟的名字,我可以确保它与包含复制按钮的组件位于相同的命名容器中,但我无法控制完整的嵌套层次结构,因此它可能是:form:foo:bar:parent:child或只是form:parent:child.所以基本上我想获得当前复合组件的前缀,但没有组件自己的ID,然后附加要从中复制的组件的ID.

这与以下问题类似:

但是,这两个答案使用PrimeFaces-sepcific功能,如@parentwidgetVar,这并不适用于我的项目.

在试验EL的隐式对象时,我基本上尝试了与第二个问题的海报相同的东西 - 结果相同:cc.parent.clientId总是空的.我也尝试cc.namingContainer.clientId了两种组合,唉 - 没有成功.特别是parent不能按预期工作的事实让我感到困惑......

那么:是否存在与组件库无关的方式来访问包含复合组件命名容器的"路径"?该如何parent对象应该工作,尤其是:我们什么时候可以使用它,何时不?

PS:我正在考虑使用复合的完整clientId然后修剪它的实际ID fn:split,但是,如果有更直接的方式我会乐意使用它.

Bal*_*usC 6

#{cc.parent}解析为UIComponent#getCompositeComponentParent()返回最接近的母体复合部件.换句话说,null当复合组件本身嵌套在另一个复合组件中时,它仅返回非.

#{cc.namingContainer}仅仅指的是#{cc}自身的根据规定完全符合UIComponent#getNamingContainer():

与"此"开始,因为是祖先返回最接近的组件NamingContainernull如果没有可以找到.

复合组件即隐式实现NamingContainer自身.

所以不幸的是,你的尝试无效.我也没有看到任何"标准API"方法来实现具体的功能要求.无法解决的CompositeComponentAttributesELResolver原因是你最终想要的.#{cc.parent}UIComponent#getParent()

但是,您可以UIComponent为复合提供一个自定义实现,它会添加一个带有唯一名称的额外getter,而该名称又可以正确委托给UIComponent#getParent().

这是一个启动示例:

@FacesComponent("myComposite")
public class MyComposite extends UINamingContainer {

    public UIComponent getParentComponent() {
        return super.getParent();
    }

}
Run Code Online (Sandbox Code Playgroud)

如果在复合接口中将其注册如下:

<cc:interface componentType="myComposite">
Run Code Online (Sandbox Code Playgroud)

然后你就可以使用了

#{cc.parentComponent.clientId}
Run Code Online (Sandbox Code Playgroud)

获取真实父级的客户端ID UIComponent.

最终你应该能够使用以下构造来引用兄弟:

process=":#{cc.parentComponent.clientId}:siblingId"
Run Code Online (Sandbox Code Playgroud)