我不确定使用<f:view>和有什么好处<f:subview>.我注意到可以在不使用它们的情况下编写JSF页面.
使用这些标签有什么好处?
wrt 如何使用f:viewParam对GET请求执行操作?
<f:metadata>
<f:viewParam name="id" value="#{tInputBean.id}" />
<f:event type="preRenderView" listener="#{tInputBean.init}" />
</f:metadata>
Run Code Online (Sandbox Code Playgroud)
我很想知道a preRenderView f:event是否放在f:metadata中是否重要.我已经检查了Java EE6教程,Java Server Faces 2.0完整参考和Core JSF2,并且没有一个在f:metadata中有f:event的例子,但我在网上看到了很多像这样的例子.
JSF2 Compl.Ref说p.540
f:metadata标记封装了用于指定Facelet视图的元数据的元素集,因此必须是f:view标记的子元素,并且可能不会出现在模板中.从JSF2.0开始,此标记的唯一目的是封装f:viewParam标记.
在f:metadata中放置f:事件(通常用于支持f:viewParam)是否具有特殊含义,或者仅仅是为了帮助将它与视觉/逻辑上的f:viewParam一起分组?
也许有人可以启发我.
如果放
<f:metadata>
<f:viewParam name="test" value="#{test.value}"/>
</f:metadata>
Run Code Online (Sandbox Code Playgroud)
在模板内,设置者
setValue永远不会被调用,即调用preRender方法'call()'而不事先调用setter(参见下面的代码示例以供参考).
但是,如果将元数据块放在合成中,则会按预期调用它.
这是正常行为还是我做错了什么?
非常感谢任何见解.
Hanspeter
供参考,这里是非工作版本的完整代码示例:
testtemplate.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:metadata>
<f:viewParam name="test" value="#{test.value}"/>
</f:metadata>
<f:event type="preRenderView" listener="#{test.call}" />
<h:head>
<title>Test Template</title>
</h:head>
<h:body>
<ui:insert name="text" />
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)
testcomposition.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="/templates/testtemplate.xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<ui:define name="text">
some text
</ui:define>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)
这里是工作 …
我有以下页面:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:o="http://omnifaces.org/ui"
xmlns:thehub="http://java.sun.com/jsf/composite/components/thehub"
template="/templates/masterTemplate.xhtml">
<f:metadata>
<f:viewParam
id="returnToViewParam"
name="returnTo"
value="#{loginMB.returnTo}"
required="true" />
<f:viewParam
id="oauth_verifierViewParam"
name="oauth_verifier"
value="#{loginMB.oauth_verifier}" />
<f:viewParam
id="oauth_tokenViewParam"
name="oauth_token"
value="#{loginMB.oauth_token}" />
<f:event
type="preRenderView"
listener="#{loginMB.preRenderView()}" />
</f:metadata>
<ui:define name="body">
<o:form
id="loginForm"
includeViewParams="true">
<div class="form-vertical well">
<h4>New Users</h4>
<h5>
<h:link outcome="signup">Click here to create an account</h:link>
</h5>
<hr />
<h4>Existing Users</h4>
<h:commandButton
id="googleLoginCommandLink"
styleClass="btn"
action="#{loginMB.redirect()}"
value="Google">
<f:param
name="returnTo"
value="#{param.returnTo}" />
</h:commandButton>
<div class="clearfix"></div>
</div>
</o:form>
</ui:define> …Run Code Online (Sandbox Code Playgroud) 根据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中使用的事件的例子.这也在这里讨论:
BalusC在哪里帮助解释:
.. <f:event>并非严格要求放在<f:metadata>中.它可以附加到任何组件...当你有一堆<f:viewParam>并且希望挂钩<f:event>以在所有那些视图参数之后调用一个动作时,确实存在于<f:metadata>内的纯自我纪录目的已经设定好了...
但我上面的经验表明,在f:模板的元数据中放置和f:事件会产生稍微不同(奇怪)的行为.为什么?
facelets ×4
jsf ×4
jsf-2 ×3
composition ×1
events ×1
omnifaces ×1
prerender ×1
subview ×1
view ×1
viewparams ×1