"空"嵌套JSF h:panelGroups和f:ajax的IllegalArgumentException

时间:2015-07-14 07:59:35

标签: jsf jsf-2

我在使用h:panelGroup更新内部嵌套f:ajax元素时遇到问题。我已将问题最小化为以下示例:

<h:form id="someForm">
    <h:panelGroup id="wrapper">
        <h:panelGroup id="content">
            Some Content
        </h:panelGroup>
    </h:panelGroup>

    <h:commandLink
        action="#{bean.changeContent()}"
        value="Do Something">
        <f:ajax render=":someForm:wrapper:content"/>
    </h:commandLink>
</h:form>

当我尝试打开该页面时,findComponent方法会抛出IllegalArgumentException而没有进一步的信息:

Severe:   Error Rendering View[/view/group/invitation/testCase.xhtml] 
   java.lang.IllegalArgumentException: wrapper
at javax.faces.component.UIComponentBase.findComponent(UIComponentBase.java:655)
at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.getResolvedId(AjaxBehaviorRenderer.java:302)
at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.appendIds(AjaxBehaviorRenderer.java:292)
at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.buildAjaxCommand(AjaxBehaviorRenderer.java:225)
at com.sun.faces.renderkit.html_basic.AjaxBehaviorRenderer.getScript(AjaxBehaviorRenderer.java:89)
...

我查看了实现,发现导致异常的以下部分:

...
result = findComponent(base, segments[i], (i == 0));
// the first element of the expression may match base.id
// (vs. a child if of base)
if (i == 0 && result == null && segments[i].equals(base.getId())) {
    result = base;
}
if (result != null && (!(result instanceof NamingContainer)) && length > 0) {
    throw new IllegalArgumentException(segments[i]);
}
...

我调试了程序,找到了组件(通过上面代码的第一行),所以我唯一的结论是h:panelGroup不是NamingContainer的实例,而是在阅读{{ 3}}并检查生成的HTML以获取其他示例,我的理解是h:panelGroup是一个命名容器。但是,当我删除包装器并告诉ajax元素直接更新content panelGroup时,不会抛出任何异常。我可能不完全理解JSF用于搜索元素的方法,如果有人能够向我解释为什么这个小例子的行为如此,我会很感激。 我在GlassFish 4.0上使用Mojarra 2.2.0

1 个答案:

答案 0 :(得分:2)

如果要从同一h:form更新/呈现组件,则无需将表单ID附加到组件ID。
所以在你的情况下

<f:ajax render="content"/> 

会为你做这份工作。

h:panelGroup不是NamingContainer组件。因此,您不需要通过嵌套其id来引用h:panelGroup的内部组件。

所以<h:panelGroup id="content">可以从外面的表单中引用someForm:content someForm:wrapper:content是错误的。这就是你得到例外的原因。

您始终可以通过右键单击和Inpect元素在浏览器中找到生成的组件ID。