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

Posted

技术标签:

【中文标题】在 JSF 2.0 中检索其他组件的客户端 ID【英文标题】:Retrieving other component's client ID in JSF 2.0 【发布时间】:2012-08-20 22:08:36 【问题描述】:

JSF 2.0 是否有用于查找另一个组件的客户端 ID 的内置方法? SO上有大约一千个与客户端ID相关的问题,并且有很多hackish方法可以做到这一点,但我想知道JSF 2.0是否带来了一种我不知道的更简单的方法。

#component.clientId 计算为给定组件自己的客户端 ID,但我想引用另一个组件的 ID。

This 博客文章提到了component.clientId,它还说#someComponent.clientId 有效,但据我所知,它没有。我相信他是在 JSF 2.0 的任何参考实现出现之前写的,所以他只是通过 JSR,也许功能发生了变化。我不确定。

我知道 PrimeFaces 和 RichFaces 都有自己的函数来返回客户端 ID,但我只是想知道是否有用于此的内置 JSF 2.0 方法。以下是一些示例:

这可以返回 outputText 的 ID。

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

根据上面的博客文章,这应该有效,但它没有。我只是没有输出。

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

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

这适用于 PrimeFaces:

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

适用于 RichFaces:

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

此外,如果可能的话,我正在寻找在更改 javax.faces.SEPARATOR_CHAR 值或在引用组件之外添加/删除容器时不会中断的解决方案。我花了很多时间来追踪由硬编码 ID 路径引起的问题。

【问题讨论】:

【参考方案1】:

您需要在视图范围内通过binding 属性为组件分配一个变量名。

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

【讨论】:

太好了。我假设binding 属性专门用于将组件公开给支持bean - 我没有意识到您也可以在范围上发布组件。非常感谢。 我也不知道你能做到这一点!我没有在文档中看到任何关于使用绑定/EL 的引用。这是 JSF 2.x 中的新功能吗? (即它在 1.2 中也可用吗?) 它一直在 JSF/EL 中。它不是特定于 JSF2。另请参阅此相关问题/答案:***.com/questions/8168302/… 没有碰撞或错误/错误绑定的问题吗?我很想拥有 clientId,但如果我冒着在组件上获取错误值的风险......那将是一个杀手 @Toskan:我不确定我是否理解你的担忧。【参考方案2】:

这对我有用。我很想知道写这样的回复是否可以。

client.html

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

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(":", "\\\\:");



【讨论】:

【参考方案3】:

因为这是我的谷歌搜索的第一批结果之一,我想知道为什么我得到了一个

javax.el.PropertyNotFoundException(找不到属性“itemId”[...])

在尝试接受的解决方案时,我想分享我的 JSF 1.2 解决方案:

UIComponent 的方法getClientId 需要一个FacesContext 参数(参见UIComponent documentation)。所以添加一个绑定到支持 bean 以及另一个返回 clientId 的方法:

xhtml:

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

豆子:

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);

请注意,您将组件绑定到的 bean 应该是请求范围的,否则您最终可能会得到 java.lang.IllegalStateException (duplicate Id for a component)(与 this topic 相比)。

【讨论】:

以上是关于在 JSF 2.0 中检索其他组件的客户端 ID的主要内容,如果未能解决你的问题,请参考以下文章

JSF 2.0 AJAX:使用 jsf.ajax.request(或其他方式)从 javascript 调用 bean 方法

JSF 2.0 动态删除组件

JSF:在没有自定义消息的情况下从验证消息中删除客户端 ID(标签、组件 ID)

在哪里放置组合组件?(JSF 2.0)

jsf 2.0 自定义组件/标签不复合

JSF 2.0:跨多个视图保留组件状态