因此,经过几天的调试,我们最终能够重现我们不理解的JSF中复合组件,ui:repeat
,p:remoteCommand
和部分状态节省之间的一些奇怪的相互作用。
方案
使用ui:repeat
的对象列表在对象列表上迭代。在每次迭代期间,包括另一个复合组件并传递参数。
<ui:composition (...)>
<ui:repeat var="myVar" value="#{cc.attrs.controller.someList}">
<namespace:myRemoteCommand someParam="SomeParam"/>
在随附的复合组件中,有一个自动运行p:remoteCommand
使用组件接口中定义的参数调用方法。
<ui:component (...)>
<p:remoteCommand actionListener="#{someBean.someMethod(cc.attrs.someParam)}"
autoRun="true"
async="true"
global="false">
但是,在someMethod(...)
中设置断点时,将传递一个空字符串。仅当部分状态保存设置为 false 。
解决方案
我们尝试了几种解决方案,以下解决方案似乎有效(但是我们不明白为什么并且不能预见可能发生的任何其他问题):
我们可以将部分状态设置为
true
。我们可以将复合组件模式更改为
ui:include
。我们可以删除一个或两个复合组件,然后直接包含内容。
问题
为什么JSF会以这种方式行事?复合组件,ui:repeat
与传递的参数之间的这种相互作用是什么,该参数取决于我们是否使用ui:include
/部分状态保存?
我们使用PrimeFaces 5.3,Glassfish 4.1,Mojarra 2.2.12,Java 8。
您的代码都很好。只是Mojarra的<ui:repeat>
被打破了。您不是<ui:repeat>
与国家管理有关的问题的第一个。
- UI内部的复选框:重复AJAX 不刷新
- 在UI中动态添加输入字段:在表单提交期间未处理重复
- 组件具有UI内部相同的ID:重复
- &lt; h:form&gt;在&lt; ui中:重复&gt;不完全有效,只有最后一个&lt; h:form&gt;已处理
- 带有自定义背式组件的复合组件嵌套在UI中时会奇怪地破裂:重复
- ui:在O中重复:树不按预期工作
问题的根本原因是#{cc}
在<ui:repeat>
需要访问树时无处可用。有效地,<ui:repeat value>
是null
。快速工作是在UIRepeat#visitTree()
方法中明确推动#{cc}
。给定的Mojarra 2.2.12,在第734行之前,使用pushComponentToEL(facesContext, null)
。
UIComponent compositeParent = getCompositeComponentParent(this);
if (compositeParent != null) {
compositeParent.pushComponentToEL(facesContext, null);
}
并在第767行之后加上popComponentFromEL(facesContext)
。
if (compositeParent != null) {
compositeParent.popComponentFromEL(facesContext);
}
如果您不从源构建Mojarra,请将UIRepeat
的整个源代码复制到项目中,维护其包装结构并在其上应用上述更改。/WEB-INF/classes
中的类具有比/WEB-INF/lib
和Server的/lib
中的类优先级。我至少创建了问题4162来解决这个问题。
一种替代方法是用MyFaces替换Mojarra,或者将<ui:repeat>
替换为基于UIData
的组件,该组件可以正确地获得状态管理,例如<h:dataTable>
或<p:dataList>
。
<p:dataList type="none" var="myVar" value="#{cc.attrs.controller.someList}">
<namespace:myRemoteCommand someParam="SomeParam" />
</p:dataList>
您可能只想应用一些CSS来摆脱小部件风格(边框等),但这很琐碎。
另请参见:
- 应该将partial_state_saving设置为false?