简体   繁体   English

当复合组件内部时,Mojarra findComponent为有效id返回null

[英]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 ,当然,没有匹配,因为form3f: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.

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