简体   繁体   English

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

[英]How to access a composite component's sibling via clientId

I have a composite component that bundles some input fields. 我有一个复合组件捆绑一些输入字段。 The component will be used multiple times on a page and contains a button to copy the values of another of these components. 该组件将在页面上多次使用,并包含一个用于复制其他组件的值的按钮。 For this I would need to access one of those siblings via its clientId as a target for an 为此,我需要通过其clientId访问其中一个兄弟姐妹作为目标

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

My problem lies in constructing this ID. 我的问题在于构建此ID。 I have the name of the sibling and I can make sure that it is located in the same naming container as the component that contains the copy button, but I can't control the complete nesting hierarchy, so it might be :form:foo:bar:parent:child or just form:parent:child . 我有兄弟的名字,我可以确保它与包含复制按钮的组件位于相同的命名容器中,但我无法控制完整的嵌套层次结构,因此它可能是:form:foo:bar:parent:child或just form:parent:child So essentially I would want to get the prefix of the current composite component, but without the component's own ID and then attach the ID of the component from which to copy. 所以基本上我想获得当前复合组件的前缀,但没有组件自己的ID,然后附加要从中复制的组件的ID。

This is similar to these questions: 这与以下问题类似:

However, both answers make use of PrimeFaces-sepcific features like @parent and widgetVar , which does not apply to my project. 但是,这两个答案都使用了PrimeFaces特有的功能,如@parentwidgetVar ,这些功能不适用于我的项目。

When experimenting with EL's implicit objects I basically tried the same things as the poster of the second question - with the same results: cc.parent.clientId is always empty. 在尝试使用EL的隐式对象时,我基本上尝试了与第二个问题的海报相同的东西 - 结果相同: cc.parent.clientId始终为空。 I also tried cc.namingContainer.clientId and some combinations of the two, alas - no success. 我也试过cc.namingContainer.clientId以及两者的一些组合,唉 - 没有成功。 Especially the fact that parent does not work as expected confuses me... 特别是parent没有按预期工作的事实让我感到困惑......

So: Is there a component-library-agnostic way to access the "path" of containing naming containers for a composite component? 那么:是否存在与组件库无关的方式来访问包含复合组件命名容器的“路径”? How is the parent object supposed to work, especially: when can we use it and when not? parent对象应该如何工作,尤其是:我们什么时候可以使用它而什么时候不能使用它?

PS: I was thinking about using the composite's full clientId and then trimming its actual ID with fn:split , however, if there was a more direct way I'd be happy to use it. PS:我正在考虑使用复合的完整clientId,然后使用fn:split修剪其实际ID,但是,如果有更直接的方式,我会乐意使用它。

The #{cc.parent} resolves to UIComponent#getCompositeComponentParent() which returns the closest parent composite component. #{cc.parent}解析为UIComponent#getCompositeComponentParent() ,它返回最接近的父复合组件。 In other words, it returns only non- null when the composite component is by itself nested in another composite component. 换句话说,当复合组件本身嵌套在另一个复合组件中时,它仅返回非null

The #{cc.namingContainer} simply refers to #{cc} itself, fully conform as specified in UIComponent#getNamingContainer() : #{cc.namingContainer}只是引用#{cc}本身,完全符合UIComponent#getNamingContainer()指定:

Starting with "this" , return the closest component in the ancestry that is a NamingContainer or null if none can be found. 从“this”开始 ,返回祖先中最接近NamingContainer组件,如果找不到则返回null

Composite components namely implicitly implement NamingContainer themselves. 复合组件即隐式实现NamingContainer本身。

So your attempts unfortunately won't work. 所以不幸的是,你的尝试无效。 I also do not see any "standard API" ways to achieve the concrete functional requirement. 我也没有看到任何“标准API”方法来实现具体的功能要求。 The CompositeComponentAttributesELResolver causes that the #{cc.parent} doesn't resolve to UIComponent#getParent() which is what you ultimately want. CompositeComponentAttributesELResolver导致#{cc.parent}无法解析为您最终需要的UIComponent#getParent()

You can however provide a custom UIComponent implementation for the composite which adds an extra getter with an unique name which in turn properly delegates to UIComponent#getParent() . 但是,您可以为复合提供自定义UIComponent实现,该实现添加一个具有唯一名称的额外getter,该名称又适当地委托给UIComponent#getParent()

Here's a kickoff example: 这是一个启动示例:

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

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

}

If you register it as follows in the composite interface: 如果在复合接口中将其注册如下:

<cc:interface componentType="myComposite">

then you'll be able to use 然后你就可以使用了

#{cc.parentComponent.clientId}

to get the client ID of the real parent UIComponent . 获取真实UIComponent的客户端ID。

Ultimately you should be able to use the following construct to refer the sibling: 最终你应该能够使用以下构造来引用兄弟:

process=":#{cc.parentComponent.clientId}:siblingId"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM