1

我有一个自定义组件,如下所示

<custom:container>
    <custom:checkbox index="0"/>
    <custom:checkbox index="1"/>
</custom:container>

所以第一次调用encodeBegin时,它会显示hit tag <custom:container>,它会尝试保存这个组件的client id,

private String containerClientId;
public void encodeBegin(FacesContext context, UIComponent component){
    if (component instanceof ManyCheckboxContainer) {            
        containerClientId = component.getClientId(context);
        return; 
    }
}

所以当我点击时 encodeEnd 会被调用<custom:checkbox index="0"/>,就像这样

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
    }
    ...
}

如果我在复合组件中没有这个自定义组件,那么一切都很好,但是一旦我将它放入复合组件中,radio.findComponent(containerClientId);返回null. 这是mojarra中的错误吗?我在 2.1.10 和 2.1.11 下对此进行了测试,行为相同。

编辑
所以我收回这一点,当我的自定义组件在两个嵌套的内部时会发生这种行为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>

所以在这种情况下,客户端ID(返回component.getClientId(context)<custom:container>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();
     }
     ...
}

所以它寻找下一个祖先NamingContainer,在我的例子中f:subView不是h:form。然后它解析客户端 id,循环遍历它,每次将 id 的一部分传递给UIComponent findComponent(UIComponent base, String id, boolean checkId). 所以第一次,这个方法以form3id 和当前 UIComponent 为 f:subView,它搜索它的所有方面和子项,看看是否有任何组件匹配form3,当然,没有一个会匹配,因为在我的结构中form3是父级。回报也是f:subView如此。null这是 Mojarra 错误还是我做错了什么。我认为客户端 id 是相对于下一个 NamingContainer 祖先而不是一直到 NamingContainer 的根?我错了吗?

4

1 回答 1

3

阅读文档后,我觉得 Mojarra 做对了。

根据文档,如果您想从树的根部进行“绝对”搜索,您应该在搜索表达式前面放置一个分隔符(冒号)。否则,如果它是 NamingContainer 或第一个父级是 NamingContainer,它将从组件本身进行相对搜索。

顺便说一句:我链接到的文档似乎与随规范分发的官方文档相同。官方规格在这里

于 2012-08-10T06:45:10.470 回答