使用ui:repeat的复合组件在调用方法中缺少参数值

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.

Bal*_*usC 5

你的代码一切都很好。只是莫贾拉的<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 次

最近记录:

8 年,11 月 前