JSF f:viewParam如果位于template.xhtml中则不调用setter

时间:2012-03-04 09:04:21

标签: jsf facelets composition viewparams

也许有人可以启发我。

如果放

<f:metadata>
  <f:viewParam name="test" value="#{test.value}"/>
</f:metadata>

在模板内部,永远不会调用setter

setValue
,即在没有事先调用setter的情况下调用preRender方法'call()'(参见下面的代码示例以供参考)。

但是,如果将元数据块放在合成中,则会按预期调用它。

这是正常行为还是我做错了什么? 非常感谢任何见解 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>

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>

这里是工作版本的完整代码示例:

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:event type="preRenderView" listener="#{test.call}" />

     <h:head>
        <title>Test Template</title>
     </h:head>

     <h:body>
        <ui:insert name="text" />
     </h:body>

</html>

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">

     <f:metadata>
        <f:viewParam name="test" value="#{test.value}"/>
     </f:metadata>

     <ui:define name="text">
        some text
     </ui:define>

</ui:composition>

1 个答案:

答案 0 :(得分:14)

这是按规格说明的。它在<f:metadata> tag documentation中提到:

  

声明此视图的元数据构面。这必须是<f:view>的孩子。 此标记必须位于给定viewId的顶级XHTML文件中,或者位于模板客户端中,但不能位于模板中。实现必须确保facet的直接子节点是UIPanel,甚至如果小平面只有一个孩子。实现必须将UIPanel的id设置为UIViewRoot.METADATA_FACET_NAME符号常量的值。

原因很简单,因为元数据应该是视图特定的,而不是模板特定的。无论如何要实现您的要求,并且您不能/不希望将<f:metadata>放在每个模板客户端的<ui:define>中,那么您最好的选择是使用一些{{1}的常见bean }。

另见: