使用 <ui:composition> 模板时,我应该在哪里声明 <f:metadata>?
Posted
技术标签:
【中文标题】使用 <ui:composition> 模板时,我应该在哪里声明 <f:metadata>?【英文标题】:When using <ui:composition> templating, where should I declare the <f:metadata>? 【发布时间】:2014-11-29 07:32:37 【问题描述】:我在将我的 JSF 应用程序转换为可添加书签的页面方面取得了很大进展,但我想知道我的做法是否正确。一个问题是 f:metadata 标签是否存在最佳实践位置?
我的典型 Facelets 客户端页面如下所示:
<ui:composition template="./pattern.xhtml">
<ui:define name="content">
<f:metadata>
<f:viewParam name="userId" value="#bean.userId" />
<f:viewParam name="startRecord" value="#bean.startRecord" />
<f:viewParam name="pageSize" value="#bean.pageSize" />
<f:viewParam name="sort" value="#bean.sort" />
</f:metadata>
<h1>Data Table</h1>
etc
所以 f:metadata 和子 f:viewParam 标记出现在我的页面正文中。我的 pattern.xhtml 模板还有一个部分(名为“header”),可以将这些标签放在标题部分中。他们应该放在那里吗?它有什么不同吗?还是我设置了一些我还没有看到的副作用?
【问题讨论】:
【参考方案1】:从技术上讲,在视图中声明 <f:metadata>
的位置无关紧要,只要它位于顶层视图中即可(因此,在使用模板时,在模板客户端中,因此不在主模板中)。构建视图时,元数据基本上不是 JSF 组件树的一部分,而是视图根的一部分(您可以通过 ViewDeclarationLanguage#getViewMetadata()
在每个视图的基础上获取)。
大多数自记录会将<f:metadata>
放在视图的顶部,这样您就可以第一眼看到任何元数据,而无需滚动到视图源代码的中途或底部。
使用普通页面时,只需将其放在<h:head>
之前。
<!DOCTYPE html>
<html lang="en"
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"
>
<f:metadata>
<f:viewParam name="userId" value="#bean.userId" />
<f:viewParam name="startRecord" value="#bean.startRecord" />
<f:viewParam name="pageSize" value="#bean.pageSize" />
<f:viewParam name="sort" value="#bean.sort" />
</f:metadata>
<h:head>
...
</h:head>
<h:body>
...
</h:body>
</html>
使用模板时,推荐的方法,如the <f:metadata>
tag documentation 中所述,是在主模板中声明一个单独的<ui:insert name="metadata">
,并让客户端在<ui:define name="metadata">
中定义<f:metadata>
。
<ui:composition template="/WEB-INF/pattern.xhtml"
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"
>
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="userId" value="#bean.userId" />
<f:viewParam name="startRecord" value="#bean.startRecord" />
<f:viewParam name="pageSize" value="#bean.pageSize" />
<f:viewParam name="sort" value="#bean.sort" />
</f:metadata>
</ui:define>
<ui:define name="content">
<h1>Data Table</h1>
...
</ui:define>
</ui:composition>
【讨论】:
我必须说这看起来比我一直在做的要干净一些。不知何故,我没有想到仅为元数据目的创建 ui:insert,但我现在会这样做。 这是否意味着不能将f:metadata
放置在例如页面模板中以使其可重用?如果在渲染每个视图之前我们想要执行一些操作,该怎么办?
@Xtreme:只需使用<f:event>
。它实际上不需要放在<f:metadata>
中。另见***.com/questions/7343220/…
@BalusC,关于把它放在<h:head>
之前,同样的<f:metadata>
tag documentation 说:This must be a child of the <f:view>
。顶层有隐含的f:view
吗?
@this:没错。这是UIViewRoot
。另见***.com/q/8883476以上是关于使用 <ui:composition> 模板时,我应该在哪里声明 <f:metadata>?的主要内容,如果未能解决你的问题,请参考以下文章
Facelets 中 ui:composition 和 ui:decorate 的区别
Win 10 应用开发UI Composition 札记:动画
UWP 利用Windows.UI.Composition实现简单的放大🔍效果