Events JSF f:模板f:元数据中的事件preRenderView,在每次访问页面时都不会调用侦听器
Mojarra-2.1.3符合Glassfish 3.1.1(与Netbeans7.1一起分发) 我有一个@SessionScoped支持bean跟踪器,带有一个侦听器void reset() 以下内容在使用template.XHTML的所有XHTML页面的f:metadata中都可以正常工作,例如/block/view.XHTML,它还接受一个查询参数id:Events JSF f:模板f:元数据中的事件preRenderView,在每次访问页面时都不会调用侦听器,events,jsf,jsf-2,prerender,Events,Jsf,Jsf 2,Prerender,Mojarra-2.1.3符合Glassfish 3.1.1(与Netbeans7.1一起分发) 我有一个@SessionScoped支持bean跟踪器,带有一个侦听器void reset() 以下内容在使用template.XHTML的所有XHTML页面的f:metadata中都可以正常工作,例如/block/view.XHTML,它还接受一个查询参数id: <f:view> <f:metadata> <f:viewParam name="
<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中。但当我这么做的时候,奇怪的事情发生了。在第一次加载/block/view.xhtml时,它只调用了一次#{tracker.reset}(无论id查询参数是什么),此后,直到我加载了另一个具有不同viewId的页面,如/actor/view.xhtml或/block/list.xhtml或/index.html,它才被再次调用
我在template.xhtml中使用#{facesContext.viewRoot.viewId}检查了viewId。从viewId的角度来看,很明显,查询参数id在区分不同的块/视图方面不起作用。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:元数据中放置f:事件与否会有区别
我问这个问题的原因是这里有很多关于Stackoverflow的例子,在template.xhtml中使用f:metadata,在template.xhtml中的f:metadata中使用f:event
BalusC说:
每个HTTP请求都会调用preRenderView事件
只有在最终XHTML页面的f:metadata中有preRenderView f:event,或者在模板的f:metadata之外,但不在模板的f:metadata之内时,这似乎才是正确的(按预期工作)
关于是否应该在模板的f:metadata中包含f:event,或者在模板中使用f:metadata,似乎存在一些争论
JSF2完整参考(Burns和Schalk)第540页规定:
f:metadata标记封装了用于为Facelets视图指定元数据的元素集,因此必须是f:view标记的子元素,并且不能出现在模板中。从JSF2.0开始,此标记的唯一用途是封装f:viewParam标记
但是有很多关于f:metadata在模板中使用的Stackoverflow的例子,也有很多f:metadata中使用的f:event的例子。这里也讨论了这一点:
BalusC对此进行了有益的解释:
。。不严格要求将容器放置在内部。它可以连接到任何组件。。它确实是为了纯粹的自我记录的目的,当你有一堆s并且想在所有这些视图参数都设置好之后钩住a来调用一个动作的时候,就放在里面
但我上面的经验表明,将和f:event放在模板的f:metadata中会产生稍微不同(奇怪)的行为。为什么?该
本身只能在模板客户端中使用,不能在主模板中使用。也就是说,它必须在您通过URL实际请求的页面中声明,而不是在
后面的页面中声明,否则它将被忽略。此特定限制与
无关
另见: