【问题标题】:Persistance of primefaces components in Spring WebflowSpring Webflow中primefaces组件的持久化
【发布时间】:2012-04-07 21:58:33
【问题描述】:

我遇到了 Spring Webflow 中 primefaces 组件的持久性问题。如果将组件作为原始页面请求的一部分进行实例化,则一切正常。但是,如果在 ajax 请求期间实例化组件,它们不会正确持久化,并且稍后检索它们时,我们会得到一个空对象。这样做的效果是,例如选项卡视图的第二个选项卡上的组件(动态=true)不起作用。一个例子:

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:c="http://java.sun.com/jsp/jstl/core">

    <h:head>
        <ui:insert name="headIncludes" />
    </h:head>
    <h:body>
        <h:form id="testForm">
            <p:tabView id="myTabView" dynamic="true">
                <p:tab title="Tab One" id="tabOne">
                    <h:panelGroup id="tabOneGroup">
                        <p:commandLink id="linkX" value="Link X" actionListener="#{sandboxBean.testCommandLinkx}" >
                            <f:ajax />
                        </p:commandLink>
                    </h:panelGroup>
                </p:tab>
                <p:tab title="Tab Two" id="tabTwo">
                    <h:panelGroup id="tabTwoGroup">
                        <p:commandLink id="linkY" value="Link Y" actionListener="#{sandboxBean.testCommandLinky}" >
                            <f:ajax /><!-- Only matters if we switch to h:commandLink -->
                        </p:commandLink>
                    </h:panelGroup>
                </p:tab>
            </p:tabView>
        </h:form>
    </h:body>
</html>

当页面第一次加载时,代表 commandlink linkX 的 UIComponent 会被实例化,并且 'actionListener' 的属性值会被保存。当我们单击“Link X”时,该属性值会再次被检索并用于调用 testCommandLinkx()。这很好用。

当我们切换到 Tab 2 时,会发出一个 ajax 请求,并且在此期间,另一个代表 linkY 的 UIComponent 会以相同的方式创建并保持不变。但是,当我们实际点击commandlink并尝试检索actionListener属性值时,发现并没有这个属性。相反,我们会收到一个全新的对象。

如果我们将 tabView 更改为 dynamic="false",则在初始页面请求期间会创建并保留两个命令链接,并且一切正常。如果我们保持 dynamic="true" 但使用 h:commandLink 而不是 p:commandLink,那么一切正常。

现在,我真的不认为这是一个 primefaces 错误,好像很多其他人也会注意到它一样。其他人也已经毫无问题地测试了这个特定的代码片段。出于同样的原因,我怀疑这是一个 webflow 错误。它似乎更有可能是我们项目中的配置错误,但我不知道在哪里。包含每个配置文件似乎有点冗长,但如果您想查看其中的内容,只需评论,我会添加它。

至于人们无疑会问的不同组件的版本:

  • Primefaces:3.0.1 和所有更高版本的动态 tabViews(因为这是第一个真正支持它的版本)但如果您使用另一个在 ajax 请求中实例化组件的构造,则可以在早期版本中重新创建它。
  • Mojarra:2.0.4(但我也尝试过 2.0.8 和 2.1.6 没有改进)
  • Spring Webflow:2.2.1(也试过2.3)
  • Tomcat:7.0.12(也尝试过其他各种)

【问题讨论】:

  • 尝试将&lt;h:form&gt; 改为&lt;p:tab&gt;。此外,那些&lt;f:ajax/&gt; 标签是不必要的。默认情况下,所有 PrimeFaces 命令链接/按钮都已被 ajaxified,这应该由接受布尔值的 ajax 属性配置。
  • 切换表单并不会改变任何东西,我担心。 p:commandLink 不需要 ,但它确保在切换到 h:commandLink 时功能相同。我不希望人们认为 h:commandLink 起作用的原因是它不是 ajax 请求。
  • 你能详细说明一下“但是,当我们实际点击commandlink并尝试检索actionListener属性值时,我们发现没有这样的属性。相反,我们收到了一个全新的对象。” 部分?你的意思是从动作监听器方法中的视图根(或动作事件参数)检索组件,然后尝试通过getValue() 从中获取命令组件的值?如果有,为什么?
  • 我自己并没有做任何特别的事情,这只是 primefaces 和 jsf 代码的内部工作。 PrimeFaces CommandLink 类扩展了 jsf 类 UIComponent(通过 UIComponentBase、UICommand 和 HtmlCommandLink)。这个 UIComponent 类有一个 StateHelper 对象,其中实际的属性值存储在地图中。当 p:commandLink 被渲染时,StateHelper.add("actionListener", "#{sandboxBean.testCommandLinkx}" ) 被调用。但是,当我们点击 commandLink 并调用 StateHelper.get("actionListener") 时,由于属性映射为空,因此返回 null。
  • 如前所述,只有在 ajax 请求期间呈现 p:commandLink 时才会发生这种情况。如果在整个页面请求期间呈现,则单击链接时 StateHelper.get("actionListener") 正确返回持久值。

标签: jsf jsf-2 primefaces spring-webflow


【解决方案1】:

这个问题似乎是 Spring WebFlow 中的一个错误,实际上已在 3 月 27 日发布的 2.3.1 中修复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    相关资源
    最近更新 更多