Mojarra 2.1。
问题实际上是关于组件查找算法。
我有以下UIRepeat
:
<h:form id="frm">
<ui:repeat id="repeater" value="#{bean.values}" var="v">
<h:panelGroup id="pg">
<!-- content -->
<h:selectBooleanCheckbox id="cb" value="#{bean.v}">
<f:ajax event="change" listener="#{bean.listener()}" render=":frm:repeater:pg" />
</h:selectBooleanCheckbox>
<!-- another content -->
</h:panelGroup>
</ui:repeat>
</h:form>
现在考虑方法AjaxBehaviorRenderer#getResolvedId:
private static String getResolvedId(UIComponent component, String id) {
UIComponent resolvedComponent = component.findComponent(id);
if (resolvedComponent == null) {
// RELEASE_PENDING i18n
throw new FacesException(
"<f:ajax> contains an unknown id '"
+ id
+ "' - cannot locate it in the context of the component "+component.getId());
}
return resolvedComponent.getClientId();
}
此方法旨在将render属性值解析为组件。现在,在调试器中,我发现在我的情况下使用以下参数调用该方法:
component = the instance of the HtmlSelectBooleanCheckbox
id = :frm:repeater:pg
现在,方法component.findComponent(id)
会返回包含clientId
- frm:repeater:0:pg
的组件。但是以component.findComponent(":frm:repeater:0:pg")
方式调用该方法会返回null
。
为什么呢?我预计结果会是一样的。我错过了什么?
答案 0 :(得分:2)
根据impl issue 2958&#34;已修复&#34;在Mojarra 2.2.5中,他们完全删除了那个nullcheck而不是通过剥离迭代索引来改进它。从那时起,人们可以指定任意客户端ID,而不会触发异常。我创建了API issue 1372并提出了解决此问题的方法。
这意味着,自Mojarra 2.2.5起,您可以ajax更新特定的<ui:repeat>
或<h:dataTable>
迭代轮,前提是模型已正确保留(即它是视图范围)。 / p>
<h:form id="form">
<ui:repeat id="list" value="#{['one','two','three']}" var="item">
<h:outputText id="item" value="#{item}" /><br/>
</ui:repeat>
<h:commandButton value="Update second item">
<f:ajax render=":form:list:1:item" />
</h:commandButton>
</h:form>
但这也意味着,自从Mojarra 2.2.5开始,你永远不会面对众所周知的&#34;&lt; f:ajax&gt;包含一个未知的ID&#39; foo&#39;无法在组件&#39; bar&#39;&#34; 错误的上下文中找到它,这对于初学者来说是令人困惑和不好的。
无关具体问题,在您的具体情况下,您也可以只执行render="pg"
而不是render=":frm:repeater:pg"
,因为渲染目标组件的命名方式完全相同容器父组件作为执行源组件。