【问题标题】:Why is Omnifaces postInvokeAction listener method called twice为什么 Omnifaces postInvokeAction 侦听器方法被调用两次
【发布时间】:2013-02-26 15:48:10
【问题描述】:

我不熟悉使用omnifaces。 从我收集到的一点点来看,在处理 flashscope 中的对象时使用 postInvokeAction 比使用 jsf preRenderView 事件更好。但我注意到的是 listener 方法被调用了两次!我觉得 preInvokeAction 类似于前阶段侦听器,而 postInvokeAction 类似于 PhaseID.INVOKE_APPLICATION 的后阶段侦听器,因此应该只为相应的事件调用一次。这个对吗?请给我解释一下。

我目前在 Mojarra 2.1.17 和 Omnifaces 1.3 上运行。

感谢您期待您的回复!

layout1.html

    <h:body>
    <p style="color: blue; font-size: 12pt;">1. This is the main content of the file.</p>
    <ui:insert name="body_contents"/>
    <p style="color: blue; font-size: 12pt;">This is the the remaining part of the document...   in layout1</p>
    </h:body>

samplepage2.html

<h:body>
    <f:view>
        <f:metadata>
            <f:viewParam name="dummy_var" value="#{sampletest.val_test}"/>
            <f:event type="postInvokeAction" listener="#{sampletest.frompostinvokeaction}" />
            <f:event type="preRenderView" listener="#{sampletest.fromprerenderview}" />
        </f:metadata>
    </f:view>
    <ui:composition template='/layout1.html'>
        <ui:define name="title_on_head">
            <style type="text/css">
                .pkssd{
                    min-width: 340px; min-height: 30px; background: appworkspace; color: blue; font-size: 11pt; font-style: italic;
                }
            </style>
        </ui:define>
        <ui:define name="body_contents">
            <p class="pkssd">This is the active content...</p>
        </ui:define>
    </ui:composition>
</h:body>

SampleTest.java

@ManagedBean(name="sampletest")
@ViewScoped
public class SampleTest {
private String val_test;    public void frompostinvokeaction(){
    System.out.println("frompostinvokeaction: val_test: " + val_test);    }
public void fromprerenderview(ComponentSystemEvent cse){
    System.out.println("fromprerenderview : val_test: " + val_test);
}
}

【问题讨论】:

  • 对我来说很好。如果您向 SSCCE 展示您是如何使用它的,那将会很有帮助。那么我们或许可以指出你的错误。

标签: jsf-2 facelets omnifaces


【解决方案1】:

您使用主/客户端模板的方式并不完全正确。它完全不符合规范,可能导致了未指定的行为。

正确的方法是:

/WEB-INF/layout1.html

<!DOCTYPE html>
<html lang="en"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
>
    <f:view>
        <ui:insert name="metadata" />
        <h:head>
            ...
            <ui:insert name="title_on_head" />
            ...
        </h:head>
        <h:body>
            ...
            <ui:insert name="body_contents" />
            ...
        </h:body>
    </f:view>
</html>

/samplepage2.html

<ui:composition template="/WEB-INF/layout1.html">
    <ui:define name="metadata">
        <f:metadata>
            <f:viewParam name="dummy_var" value="#{sampletest.val_test}"/>
            <f:event type="postInvokeAction" listener="#{sampletest.frompostinvokeaction}" />
            <f:event type="preRenderView" listener="#{sampletest.fromprerenderview}" />
        </f:metadata>
    </ui:define>

    <ui:define name="title_on_head">
        <style type="text/css">
            .pkssd{
                min-width: 340px; min-height: 30px; background: appworkspace; color: blue; font-size: 11pt; font-style: italic;
            }
        </style>
    </ui:define>

    <ui:define name="body_contents">
        <p class="pkssd">This is the active content...</p>
    </ui:define>
</ui:composition>

(是的,这是完整的文件,&lt;ui:composition&gt; 之外没有什么

另见:

【讨论】:

  • 感谢 BalusC!我按照建议进行了重构,但 postInvokeAction 方法仍然被调用了两次。请问有什么想法吗?感谢您的一贯回应。
  • 您是否有可能拥有 CDI 的 beans.xml 并使用早于 1.1.11 的 Weld?如果是这样,请参阅 stackoverflow.com/questions/14598720/… 和随后的 issues.jboss.org/browse/WELD-1247
  • 不。我不使用那个。只需使用 ManagedBean 和 ViewScoped。上面已经显示了完整的代码。我的文件中也没有 beans.xml。请指教
  • 对不起,我无法复制它。您使用的是哪个服务器?
  • 你好 BalusC,我在 Glassfish3.1.2、mojarra 2.1.17 上运行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-02
  • 2019-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
相关资源
最近更新 更多