简体   繁体   English

在JSF 2.0中检索其他组件的客户端ID

[英]Retrieving other component's client ID in JSF 2.0

Does JSF 2.0 have a built-in method for finding the client ID of another component? JSF 2.0是否有内置方法来查找另一个组件的客户端ID? There are about a thousand client ID-related questions on SO and there are a lot of hackish methods to do this, but I'm wondering if JSF 2.0 brought a simpler method that I just don't know. 在SO上有大约一千个与客户端ID相关的问题,并且有很多hackish方法可以做到这一点,但我想知道JSF 2.0是否带来了一个我不知道的更简单的方法。

#{component.clientId} evaluates to a given component's own client ID, but I want to reference another component's ID. #{component.clientId}计算给定组件自己的客户端ID,但我想引用另一个组件的ID。

This blog post mentions component.clientId , and it also says #{someComponent.clientId} works, but from what I can tell it does not. 这篇博客文章提到了component.clientId ,它也说#{someComponent.clientId}可以工作,但从我可以告诉它没有。 I believe he wrote that before any reference implementations of JSF 2.0 were out, so he was just going by the JSR and maybe that functionality changed. 我相信他在JSF 2.0的任何参考实现出来之前都写过,所以他只是去了JSR,也许这个功能发生了变化。 I'm not sure. 我不确定。

I know PrimeFaces and RichFaces both have their own functions to return a client ID, but I'm just wondering if there's a built-in JSF 2.0 method for this. 我知道PrimeFaces和RichFaces都有自己的函数来返回客户端ID,但我只是想知道是否有内置的JSF 2.0方法。 Here are some examples: 这里有些例子:

This works to return the outputText's ID. 这可以返回outputText的ID。

`<h:outputText value="My client ID : #{component.clientId}" />`

According to the blog post above, this should work, but it does not. 根据上面的博客文章,这应该有效,但事实并非如此。 I just get no output. 我没有输出。

`<h:button id="sampleButton" value="Sample" />`

`<h:outputText value="sampleButton's client ID : #{sampleButton.clientId}" />`

This works in PrimeFaces: 这适用于PrimeFaces:

`<h:outputText value="PrimeFaces : sampleButton's client ID : #{p:component('sampleButton')}" />` 

Works in RichFaces: 在RichFaces中工作:

`<h:outputText value="RichFaces : sampleButton's client ID : #{rich:clientId('sampleButton')}" />`

Also, if at all possible I'm looking for solutions that won't break if I change the javax.faces.SEPARATOR_CHAR value or if I add/remove containers outside the referenced components. 此外,如果我可能的话,我正在寻找不会破坏的解决方案,如果我更改javax.faces.SEPARATOR_CHAR值或者我在引用的组件之外添加/删除容器。 I've spent plenty of time tracking down issues caused by hard-coded ID paths. 我花了很多时间来追踪由硬编码ID路径引起的问题。

You need to assign the component a variable name in the view scope by binding attribute. 您需要通过binding属性在视图范围中为组件分配变量名称。

<h:button id="sampleButton" binding="#{sampleButton}" value="Sample" />
<h:outputText value="sampleButton's client ID : #{sampleButton.clientId}" />

This worked for me. 这对我有用。 I would be interested to know if it is Ok to write response like this though. 我很想知道写这样的回答是否可以。

client.html client.html

<h:outputText value="#{UIHelper.clientId('look-up-address-panel-id')}" />

UIHelper.java UIHelper.java

@ManagedBean(name = "UIHelper", eager = true)
@ApplicationScoped
public class UIHelper
{

public String clientId(final String id)
{
  FacesContext context = FacesContext.getCurrentInstance();
  UIViewRoot root = context.getViewRoot();
  final UIComponent[] found = new UIComponent[1];
  root.visitTree(new FullVisitContext(context), new VisitCallback()
  {
    @Override
    public VisitResult visit(VisitContext context, UIComponent component)
    {
      if (component.getId().equals(id))
      {
        found[0] = component;
        return VisitResult.COMPLETE;
      }
      return VisitResult.ACCEPT;
    }
  });
  return found[0] == null ? "" : "#" + found[0].getClientId().replace(":", "\\\\:");
}

}

Since this was among the first results of my google search and I wondered why I got a 由于这是我的谷歌搜索的第一个结果之一,我想知道为什么我有一个

javax.el.PropertyNotFoundException (Property 'itemId' not found [...]) javax.el.PropertyNotFoundException(未找到属性'itemId'[...])

when trying the accepted solution, I would like to share my solution for JSF 1.2: 在尝试接受的解决方案时,我想分享我的JSF 1.2解决方案:

The UIComponent 's method getClientId needs a FacesContext parameter (see UIComponent documentation ). UIComponent的方法getClientId需要一个FacesContext参数(参见UIComponent文档 )。 So add a binding to the backing bean and also another method that returns the clientId: 所以添加一个绑定到支持bean以及另一个返回clientId的方法:

xhtml: XHTML:

<h:button id="sampleButton" binding="#{backingBean.sampleButton}" value="Sample" />
<h:outputText value="sampleButton's client ID : #{backingBean.sampleButtonClientId}" />

Bean: 豆:

private UIComponent sampleButton;

public UIComponent getSampleButton() {
    return sampleButton;
}

public void setSampleButton(final UIComponent sampleButton) {
    this.sampleButton = sampleButton;
}

public String getSampleButtonClientId() {
    final FacesContext context = FacesContext.getCurrentInstance();
    return sampleButton.getClientId(context);
}

Notice that the bean you are binding your component to should be request scoped or else you could end up with a java.lang.IllegalStateException (duplicate Id for a component) (compare to this topic ). 请注意,您绑定组件的bean应该是请求作用域,否则您最终可能会遇到java.lang.IllegalStateException (duplicate Id for a component) (与此主题相比 )。

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

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