实际上,在我的JSF应用程序中,我有这段代码可以根据其ID计算组件 clientId :
Actually in my JSF application I have this code to compute a component clientId from its id:
public static String getComponentClientId(String id) { try { FacesContext fctx = FacesContext.getCurrentInstance(); UIComponent found = getComponentWithId(fctx.getViewRoot(), id); if (found!=null) return found.getClientId(fctx); else return null; } catch (Exception e) { return null; } } public static UIComponent getComponentWithId(UIComponent parent, String id) { for (Iterator<UIComponent> chs = parent.getFacetsAndChildren(); chs.hasNext();) { UIComponent ch = chs.next(); if (ch.getId().equalsIgnoreCase(id)) return ch; else { UIComponent found = getComponentWithId(ch, id); if (found!=null) return found; } } return null; }该方法有效,但它会在视图组件树中导航,因此效率可能非常低,尤其是在存在人口众多的页面的情况下.我不知道有什么聪明的方法或API可以使工作更快/更轻松?
The method works, but it navigate through the view component tree, so it can be very inefficient, specially in presence of highly populated pages. There is a clever way or an API that I don't know to make the job faster/easier?
推荐答案我不知道.
很难缓存此信息,因为:
It is difficult to cache this information, because:
在尝试其他方法之前,我将证明这是一个问题.
I would prove that this is a problem before trying another approach.
您没有说 clientId 的用途,但我猜想它是对某种形式的JavaScript支持的.考虑编写自定义组件并通过发出标记它的渲染器.可以与 for 属性,类似于标签控件.在相同的 NamingContainer 比较容易.您可以在渲染器实现中使用如下代码:
You don't say what you need the clientIds for, but I'm guessing it is for some form of JavaScript support. Consider writing a custom component and emitting your markup via its renderer. This could be used with a for attribute, similar to the label control. Finding a neighbour in the same NamingContainer is relatively easy. You might use code like this in your renderer implementation:
// untested code! String clientId = mycomponent.getClientId(context); // get id of target control String _for = mycomponent.getFor(); int n = clientId.lastIndexOf(NamingContainer.SEPARATOR_CHAR); String targetClientId = clientId.substring(0, n) + NamingContainer.SEPARATOR_CHAR + _for; ResponseWriter writer = context.getResponseWriter(); // write markup组件通常通常需要共享一个命名容器以利用彼此的 clientId ,因此这并不是一个很大的限制.如果您可以将该组件作为子组件,则找到父组件会更容易.
Components usually need to share a naming container to make use of each other's clientId anyway, so this isn't a big constraint. If you can make the component a child, it is easier to find a parent.
当然,这种方法也有问题.它使您的UI树变得更大,对生命周期处理和状态管理产生连锁反应.权衡是否值得进行测试.
Of course, this approach has problems too. It makes your UI tree even bigger, with a knock-on effect on lifecycle processing and state-management. Whether the trade-off is worth it would require testing.
我在周末想到了这个.由于50%的JSF查询似乎都是关于如何使用ID的,所以我写了一篇文章,以便我可以介绍一下人们- JSF:使用组件ID .在其中包括一种用于缓存ID (有点!)和一些示例代码的机制.
I thought about this over the weekend. Since 50% of JSF queries seem to be about how to work with IDs, I wrote a post so I can just refer people to it - JSF: working with component IDs. In includes a mechanism for caching the IDs (sort of!) with some sample code.
更多推荐
一种计算UIComponent clientID的有效方法?
发布评论