【发布时间】:2012-06-19 15:12:56
【问题描述】:
按照 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:事件)。这适用于 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 状态为When to use f:viewAction / preRenderView versus PostConstruct?:
每个 HTTP 请求都会调用 preRenderView 事件。
如果我在最终 XHTML 页面的 f:metadata 中或在模板的 f:metadata 之外但不在 f:模板的元数据。
关于是否应该在模板的 f:metadata 中包含 f:event 或在模板中使用 f:metadata 似乎存在一些争论。
JSF2 完整参考(Burns 和 Schalk)第 540 页指出:
f:metadata 标记封装了一组元素,用于指定 Facelets 视图的元数据,因此必须是 f:view 标记的子级,并且不能出现在模板中。从 JSF2.0 开始,这个标签的唯一目的就是封装 f:viewParam 标签。
但是在 Stackoverflow 上有很多 f:metadata 在模板中使用的示例,并且有很多 f:event 在 f:metadata 中使用的示例。这里也有讨论:
Does it matter whether place f:event inside f:metadata or not?
BalusC 有帮助的解释:
..
并不严格要求放在 中。它可以连接到任何组件。 .. 当你有一堆 并且想要挂钩 以在所有这些视图参数之后调用一个动作时,它确实是为了纯粹的自我记录目的放在 中已设置。 ..
但我上面的经验表明,将 f:event 放在模板的 f:metadata 中会产生略微不同(奇怪)的行为。为什么?
【问题讨论】:
标签: events jsf jsf-2 prerender