[英]Mojarra findComponent return null for valid id when inside composite component
I have a custom component that look as follow 我有一个自定义组件,如下所示
<custom:container>
<custom:checkbox index="0"/>
<custom:checkbox index="1"/>
</custom:container>
so when encodeBegin first call, it will show hit the tag <custom:container>
, and it will try to save this component cliend id, 所以当encodeBegin第一次调用时,它会显示标签<custom:container>
,它会尝试保存这个组件的cliend id,
private String containerClientId;
public void encodeBegin(FacesContext context, UIComponent component){
if (component instanceof ManyCheckboxContainer) {
containerClientId = component.getClientId(context);
return;
}
}
so encodeEnd get called when I hit <custom:checkbox index="0"/>
, like this 所以当我点击<custom:checkbox index="0"/>
时会调用encodeEnd,就像这样
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
...
if (component instanceof Checkbox) {
renderCheckbox(context, (Checkbox) component);
}
...
}
protected void renderCheckbox(FacesContext facesContext, InforRadio radio) throws IOException {
...
UIComponent uiComponent = radio.findComponent(containerClientId);
if(uiComponent == null){
//throw error
}
...
}
If I DO NOT have this custom component inside composite component then everything work great, but once I put it in a composite component, radio.findComponent(containerClientId);
如果我在复合组件中没有这个自定义组件,那么一切都很radio.findComponent(containerClientId);
,但是一旦我把它放在一个复合组件中,就radio.findComponent(containerClientId);
return null
. 返回null
。 Is this a bug in mojarra? 这是mojarra的一个错误吗? I test this under 2.1.10 and 2.1.11, same behavior. 我在2.1.10和2.1.11下测试了这个,行为相同。
EDIT 编辑
So I take that back, this behavior happen when my custom component is inside two nested NamingContainer
, so something like this 所以我把它拿回去,当我的自定义组件在两个嵌套的NamingContainer
,会发生这种情况,所以这样的事情
<h:form id="myForm">
<f:subView id="myView">
<custom:container id="myCustom">
<custom:checkbox index="0"/>
<custom:checkbox index="1"/>
</custom:container>
</f:subView>
</h:form>
so in this case the client id (that return by component.getClientId(context)
) for <custom:container>
is myForm:myView:myCustom
, but inside Mojarra, the findComponent
method has this 所以在这种情况下, <custom:container>
的客户端id(由component.getClientId(context)
返回component.getClientId(context)
是myForm:myView:myCustom
,但在Mojarra中, findComponent
方法有这个
public UIComponent findComponent(String expr) {
...
else if (!(base instanceof NamingContainer)) {
// Relative expressions start at the closest NamingContainer or root
while (base.getParent() != null) {
if (base instanceof NamingContainer) {
break;
}
base = base.getParent();
}
...
}
so it looks for the next ancestor NamingContainer
, which in my case is the f:subView
not the h:form
. 所以它寻找下一个祖先NamingContainer
,在我的例子中是f:subView
而不是h:form
。 It then parse the client id, loop through it, each time passing piece of the id to the UIComponent findComponent(UIComponent base, String id, boolean checkId)
. 然后它解析客户端id,循环遍历它,每次将id传递给UIComponent findComponent(UIComponent base, String id, boolean checkId)
。 So the first time in, this method take form3
as id and current UIComponent is f:subView, it search for all its facets and children to see if any component match form3
, of course, none will match since form3
is the parent of f:subView
in my structure. 所以第一次,这个方法将form3
作为id,当前的UIComponent是f:subView,它搜索其所有facet和子form3
以查看是否有任何组件匹配form3
,当然,没有匹配,因为form3
是f:subView
的父节点f:subView
我的结构中的f:subView
。 So null
is return. 所以返回null
。 Is this Mojarra bugs or am I doing some wrong. 这是Mojarra的错误还是我做错了。 I thought that the client id is relative from the next NamingContainer ancestor instead of all the way to the root of the NamingContainer? 我认为客户端ID是从下一个NamingContainer祖先相对而不是一直到NamingContainer的根目录? Am I wrong on that? 我错了吗?
After reading the docs it seems to me that Mojarra got it right. 在阅读了文档之后,我觉得Mojarra做对了。
According to the docs you should place a seperator (a colon) in front of your search expression if you want to do an "absolute" search from the root of your tree. 根据文档,如果要从树的根目录进行“绝对”搜索,则应在搜索表达式前面放置一个分隔符(冒号)。 Otherwise it will do a relative search from the component itself if it is a NamingContainer or the first parent that is a NamingContainer. 否则,它将从组件本身进行相对搜索,如果它是NamingContainer或第一个父级是NamingContainer。
BTW: The docs I linked to appear to be the same as the official docs distributed with the specs. 顺便说一句:我链接的文档看起来与分发规范的官方文档相同。 Official specs are here . 官方规格在这里 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.