使用 <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】:

从技术上讲,在视图中声明 &lt;f:metadata&gt; 的位置无关紧要,只要它位于顶层视图中即可(因此,在使用模板时,在模板客户端中,因此不在主模板中)。构建视图时,元数据基本上不是 JSF 组件树的一部分,而是视图根的一部分(您可以通过 ViewDeclarationLanguage#getViewMetadata() 在每个视图的基础上获取)。

大多数自记录会将&lt;f:metadata&gt; 放在视图的顶部,这样您就可以第一眼看到任何元数据,而无需滚动到视图源代码的中途或底部。

使用普通页面时,只需将其放在&lt;h:head&gt; 之前。

<!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 &lt;f:metadata&gt; tag documentation 中所述,是在主模板中声明一个单独的&lt;ui:insert name="metadata"&gt;,并让客户端在&lt;ui:define name="metadata"&gt; 中定义&lt;f:metadata&gt;

<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:只需使用&lt;f:event&gt;。它实际上不需要放在&lt;f:metadata&gt; 中。另见***.com/questions/7343220/… @BalusC,关于把它放在&lt;h:head&gt; 之前,同样的&lt;f:metadata&gt; tag documentation 说:This must be a child of the &lt;f:view&gt;。顶层有隐含的f:view 吗? @this:没错。这是UIViewRoot。另见***.com/q/8883476

以上是关于使用 <ui:composition> 模板时,我应该在哪里声明 <f:metadata>?的主要内容,如果未能解决你的问题,请参考以下文章

Facelets 中 ui:composition 和 ui:decorate 的区别

JSF ui:composition 和复合组件的问题

Win 10 应用开发UI Composition 札记:动画

UWP 利用Windows.UI.Composition实现简单的放大🔍效果

Win 10 应用开发UI Composition 札记:绘制图形

Win 10 应用开发UI Composition 札记:灯光