JSF f:模板中的事件preRenderView f:元数据,每次访问页面时都没有调用监听器

时间:2012-06-17 06:52:35

标签: events jsf jsf-2 prerender

根据Glassfish3.1.1的Mojarra-2.1.3(随Netbeans7.1一起发布)

我有一个带有侦听器void reset()的@SessionScoped辅助bean跟踪器。

以下在f:使用template.xhtml的所有XHTML页面的元数据中都可以正常工作,例如/block/view.xhtml,它也带有查询参数id:

<f:view>
    <f:metadata>
        <f:viewParam name="id" value="#{blockManager.id}"/>
        <f:event type="preRenderView" listener="#{tracker.reset}"/>            
    </f:metadata>
</f:view>

<ui:composition template="/template.xhtml">

正如预期的那样,每当我加载(GET)或重新加载页面时,无论id查询参数是什么,都会调用#{tracker.reset}侦听器(如调试日志记录所示)。

然而,在每个XHTML页面(我有数百个)中包含f:事件是很繁琐的,我先尝试将它放在我的template.xhtml的f:metadata中。但是当我做了一些奇怪的事情时。它只调用#{tracker.reset}一次,第一次加载/block/view.xhtml(无论id查询参数是什么),然后在我加载另一个具有不同viewId的页面之后再没有调用它,例如/actor/view.xhtml,或/block/list.xhtml或/index.html。

我使用template.xhtml中的#{facesContext.viewRoot.viewId}检查了viewId。从viewId的角度来看很清楚,查询参数id在区分使用不同id查询参数调用的不同block / view.xhtml?id = [id]页面时没有任何作用,viewId总是只是'/ block /view.xhtml”。

在编写此stackoverflow发布期间,我发现了我的问题的解决方案:只需将f:event放在f:metadata.xhtml的元数据之外(我在template.xhtml中使用f:metadata进行分组) F:事件)。这适用于template.xhtml:

<f:metadata>
..
</f:metadata>
<f:event type="preRenderView" listener="#{tracker.reset}"/>
<h:head>

但我仍然有以下问题:

问:为什么我是否在模板中的f:元数据中放置f:事件会有所不同?

我问的原因是Stackoverflow上有很多例子,在template.xhtml中使用f:元数据,在f:元素模板中使用f:事件。

BalusC在When to use f:viewAction / preRenderView versus PostConstruct?陈述:

  

在每个HTTP请求上调用preRenderView事件。

如果我在最终XHTML页面的f:元数据中有preRenderView f:事件,或者在模板的f:元数据之外,但在f:中没有,那么这似乎是真的(按预期工作)模板的元数据。

关于是否应该在f:模板的元数据中使用f:event,或者在模板中使用f:metadata,似乎存在争议。

JSF2完全参考(Burns和Schalk)p.540陈述:

  

f:metadata标记封装了用于指定Facelets视图元数据的元素集,因此必须是f:view标记的子元素,并且可能不会出现在模板中。从JSF2.0开始,此标记的唯一目的是封装f:viewParam标记。

但是有很多关于f的Stackoverflow的例子:在模板中使用的元数据,并且有很多f:在f:metadata中使用的事件的例子。这也在这里讨论:

Does it matter whether place f:event inside f:metadata or not?

BalusC在哪里帮助解释:

  

..&lt; f:event&gt;并非严格要求放在&lt; f:metadata&gt;内。它可以附加到任何组件。 ..这确实适用于放置在&lt; f:metadata&gt;内的纯自我纪录目的。每当你有一堆&lt; f:viewParam&gt; s并希望挂钩&lt; f:event&gt;在设置了所有这些视图参数后调用操作。 ..

但我上面的经验表明,在f:模板元数据中放置和f:事件会产生稍微不同(奇怪)的行为。为什么?

1 个答案:

答案 0 :(得分:8)

<f:metadata>本身只能在模板客户端中使用,而不能在主模板中使用。即它必须在您实际通过URL请求的页面中声明,而不是在<ui:composition template>后面的页面内声明,否则它将被忽略。此特定限制与<f:event>无关。

另见:

相关问题