我有一个自定义组件,如下所示
<custom:container>
<custom:checkbox index="0"/>
<custom:checkbox index="1"/>
</custom:container>
因此,当encodeBegin第一次调用时,它将显示命中标记
<custom:container>
,并且它将尝试保存此组件cliend 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
。这是莫哈拉的一只虫子吗?我在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)
)对于
<自定义:容器>
是
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();
}
...
}
所以它在寻找下一个祖先
Naming容器
,在我的情况下是
f:subView
不是
h:form
然后,它解析客户端id,循环通过它,每次都将id的一部分传递给
UIComponent findComponent(UIComponent base, String id, boolean checkId)
。所以第一次在,这个方法
form3
由于id和当前UIComponent是f:subView,它会搜索其所有方面和子项,以查看是否有任何组件匹配
形式3
当然,没有人能比得上
形式3
是的父级
f: 子视图
在我的结构中。所以
无效的
是返回。这是Mojarra bug还是我做错了什么。我认为客户端id是相对于下一个NamingContainer祖先的,而不是一直到NamingContainer的根?我错了吗?