Nep*_*tyz 6 jsf primefaces composite-component mojarra uirepeat
因此,经过几天的调试,我们最终能够重现复合组件之间的一些奇怪的交互ui:repeat
,p:remoteCommand
以及我们不理解的JSF中的部分状态保存.
复合组件使用迭代对象列表ui:repeat
.在每次迭代期间,包含另一个复合组件并传递参数.
<ui:composition (...)>
<ui:repeat var="myVar" value="#{cc.attrs.controller.someList}">
<namespace:myRemoteCommand someParam="SomeParam"/>
Run Code Online (Sandbox Code Playgroud)
在包含的复合组件中,有一个自动运行p:remoteCommand
调用方法,该方法使用组件接口中定义的参数.
<ui:component (...)>
<p:remoteCommand actionListener="#{someBean.someMethod(cc.attrs.someParam)}"
autoRun="true"
async="true"
global="false">
Run Code Online (Sandbox Code Playgroud)
但是,在设置断点时someMethod(...)
,会传递一个空字符串.仅当部分状态保存设置为false时才会发生这种情况.
我们尝试了几种解决方案,以下方案似乎有效(但我们不明白为什么,也无法预见可能发生的任何其他问题):
我们可以将部分状态保存设置为true
.
我们可以将复合组件模式更改为ui:include
.
我们可以删除一个或两个复合组件,而是直接包含内容.
题
为什么JSF会这样做?复合组件ui:repeat
和参数传递之间的这种交互是什么,这取决于我们是否使用ui:include
/部分状态保存?
我们使用的是Primefaces 5.3,Glassfish 4.1,Mojarra 2.2.12,Java 8.
你的代码一切都很好。只是莫贾拉的<ui:repeat>
坏了。您不是第一个面临状态管理相关问题的人<ui:repeat>
。
您问题的根本原因是#{cc}
目前无法<ui:repeat>
访问该树。实际上,<ui:repeat value>
是null
. 一个快速的解决方法是显式推送#{cc}
inUIRepeat#visitTree()
方法。给定 Mojarra 2.2.12,在第 734 行之前添加以下行并使用pushComponentToEL(facesContext, null)
.
UIComponent compositeParent = getCompositeComponentParent(this);
if (compositeParent != null) {
compositeParent.pushComponentToEL(facesContext, null);
}
Run Code Online (Sandbox Code Playgroud)
并在第 767 行之后添加以下行并使用popComponentFromEL(facesContext)
.
if (compositeParent != null) {
compositeParent.popComponentFromEL(facesContext);
}
Run Code Online (Sandbox Code Playgroud)
如果您不从源代码构建 Mojarra,请将整个源代码复制UIRepeat
到您的项目中,维护其包结构并对其应用上述更改。中的类比服务器中的类/WEB-INF/classes
具有更高的类加载优先级。我至少创建了问题 4162来解决这个问题。/WEB-INF/lib
/lib
另一种方法是用 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>
Run Code Online (Sandbox Code Playgroud)
您可能只想应用一些 CSS 来摆脱小部件样式(边框等),但这很简单。
归档时间: |
|
查看次数: |
278 次 |
最近记录: |