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

Web*_*ter 3 events jsf prerender jsf-2

根据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">
Run Code Online (Sandbox Code Playgroud)

正如所料,每当我加载(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:events ).这适用于template.xhtml:

<f:metadata>
..
</f:metadata>
<f:event type="preRenderView" listener="#{tracker.reset}"/>
<h:head>
Run Code Online (Sandbox Code Playgroud)

但我仍然有以下问题:

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

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

BalusC在何时使用f:viewAction/preRenderView与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中使用的事件的例子.这也在这里讨论:

是否在f:元数据中放置f:event是否重要?

BalusC在哪里帮助解释:

.. <f:event>并非严格要求放在<f:metadata>中.它可以附加到任何组件...当你有一堆<f:viewParam>并且希望挂钩<f:event>以在所有那些视图参数之后调用一个动作时,确实存在于<f:metadata>内的纯自我纪录目的已经设定好了...

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

Bal*_*usC 9

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

也可以看看: