"empty" 带有嵌套 JSF h:panelGroups 和 f:ajax 的 IllegalArgumentException
"empty" IllegalArgumentException with nested JSF h:panelGroups and f:ajax
我在使用 f:ajax
更新内部嵌套 h:panelGroup
元素时遇到问题。我已将我的问题最小化为以下示例:
<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
的实例,但是看了之后this post 并检查生成的 HTML 以获取其他示例我的理解是 h:panelGroup
是一个命名容器。但是,当我删除包装器并告诉 ajax 元素直接更新 content
panelGroup
时,不会抛出任何异常。我可能不完全理解 JSF 用于搜索元素的方法,如果有人能向我解释为什么这个小示例会以这种方式运行,我将不胜感激。
我在 GlassFish 4.0
上使用 Mojarra 2.2.0
当您想要 update/render 来自同一 h:form
的组件时,您不需要将表单 ID 附加到组件 ID。
所以在你的情况下
<f:ajax render="content"/>
会为您完成这项工作。
并且 h:panelGroup
不是 NamingContainer 组件。所以你不需要通过嵌套它的 id 来引用 h:panelGroup
的内部组件。
所以 <h:panelGroup id="content">
可以从外部形式引用 someForm:content
。
someForm:wrapper:content
是错误的。这就是您获得异常的原因。
您总是可以通过右键单击并检查元素在浏览器中找到生成的组件id。
我在使用 f:ajax
更新内部嵌套 h:panelGroup
元素时遇到问题。我已将我的问题最小化为以下示例:
<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
的实例,但是看了之后this post 并检查生成的 HTML 以获取其他示例我的理解是 h:panelGroup
是一个命名容器。但是,当我删除包装器并告诉 ajax 元素直接更新 content
panelGroup
时,不会抛出任何异常。我可能不完全理解 JSF 用于搜索元素的方法,如果有人能向我解释为什么这个小示例会以这种方式运行,我将不胜感激。
我在 GlassFish 4.0
当您想要 update/render 来自同一 h:form
的组件时,您不需要将表单 ID 附加到组件 ID。
所以在你的情况下
<f:ajax render="content"/>
会为您完成这项工作。
并且 h:panelGroup
不是 NamingContainer 组件。所以你不需要通过嵌套它的 id 来引用 h:panelGroup
的内部组件。
所以 <h:panelGroup id="content">
可以从外部形式引用 someForm:content
。
someForm:wrapper:content
是错误的。这就是您获得异常的原因。
您总是可以通过右键单击并检查元素在浏览器中找到生成的组件id。