根据 Glassfish3.1.1 的 Mojarra-2.1.3(随 Netbeans7.1 分发)
我有一个带有监听器 void reset() 的 @SessionScoped 后备 bean Tracker。
以下在所有使用 template.xhtml 的 XHTML 页面的 f:metadata 中都可以正常工作,例如 /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:event 是很乏味的,我首先尝试将它包含在我的 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对于区分不同的block/view.xhtml?id=[id]页面没有任何作用,调用不同的id查询参数,viewId永远只是'/block /view.xhtml'。
在撰写此 stackoverflow 帖子期间,我发现了问题的解决方案:只需将 f:event 放在 template.xhtml 的 f:metadata 之外(我在 template.xhtml 中使用 f:metadata 对 f:events 进行分组)。这适用于 template.xhtml:
<f:metadata>
..
</f:metadata>
<f:event type="preRenderView" listener="#{tracker.reset}"/>
<h:head>
但我仍然有以下问题:
问:为什么在模板的 f:metadata 中放置 f:event 会有所不同?
我问的原因是 Stackoverflow 上有很多例子,包括在 template.xhtml 中使用 f:metadata,以及在模板中使用 f:metadata 中的 f:event。
BalusC 在何时使用 f:viewAction / preRenderView 与 PostConstruct 中声明?:
在每个 HTTP 请求上都会调用 preRenderView 事件。
如果我在最终 XHTML 页面的 f:metadata 或模板的 f:metadata 之外,但不在 f:metadata 的 f:metadata 中,这似乎是正确的(按预期工作)模板。
关于是否应该在模板的 f:metadata 中包含 f:event 或在模板中使用 f:metadata 似乎存在一些争论。
JSF2 Complete Reference (Burns and Schalk) p.540 状态:
f:metadata 标记封装了用于指定 Facelets 视图的元数据的元素集,因此必须是 f:view 标记的子级,并且不能出现在模板中。从 JSF2.0 开始,此标记的唯一目的是封装 f:viewParam 标记。
但是在模板中使用 f:metadata 的 Stackoverflow 上有很多示例,并且在 f:metadata 中使用 f:event 的示例也很多。这里也讨论了:
是否将 f:event 放在 f:metadata 中是否重要?
BalusC 帮助解释的地方:
.. <f:event> 并不严格要求放在 <f:metadata> 内。它可以连接到任何组件。.. 当你有一堆 <f:viewParam> 并且想要挂钩 <f:event> 以在所有这些视图参数之后调用一个动作时,它确实是为了纯粹的自我记录目的放在 <f:metadata> 中已设置。..
但是我上面的经验表明,在模板的 f:metadata 中放置和 f:event 会产生稍微不同的(奇怪的)行为。为什么 ?