JSF f: viewParam не вызывает сеттер, если он находится в template.xhtml - PullRequest
7 голосов
/ 04 марта 2012

Возможно, кто-то может просветить меня.

Если поместить

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

в шаблон, метод set

setValue
никогда не вызывается, то есть вызывается метод preRender 'call ()'без предварительного вызова setter (см. ниже в примере кода для справки).

Если, однако, если поместить блок метаданных внутри композиции, он будет вызван, как и ожидалось.

Это нормальное поведение или нетЯ что-то не так делаю?
Большое спасибо за понимание* 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 Ответ

14 голосов
/ 04 марта 2012

Это по спецификации. Это упомянуто в <f:metadata> документации тега :

Объявите фасет метаданных для этого представления. Это должно быть дитя <f:view>. Этот тег должен находиться в файле XHTML верхнего уровня для данного viewId или в клиенте шаблона, но не в шаблоне. Реализация должна гарантировать, что прямым потомком фасета является UIPanel, даже если есть только один ребенок аспекта. Реализация должна установить идентификатор UIPanel равным значению символической константы UIViewRoot.METADATA_FACET_NAME.

Простая причина в том, что метаданные должны быть специфичными для представления, а не для конкретного шаблона. В любом случае, чтобы выполнить ваше требование, и вы не можете / не хотите помещать <f:metadata> внутри <ui:define> каждого клиента шаблона, тогда вам лучше всего использовать какой-нибудь общий компонент с @ManagedProperty.

Смотри также:

...