当父视图中存在“viewParam”时,将忽略“preRenderComponent”

时间:2013-06-27 17:15:46

标签: jsf metadata composite-component

每当我的组件被渲染时,我需要一个方法来执行,即第一次和每次更新时都会创建它。

一种方法是使用f:metadata和f:event作为事件“preRenderComponent”。除非我在拥有组件的视图中有f:viewParam的f:元数据,否则它的效果非常好。如果父视图中有f:viewParam,则组件中的f:event将被忽略。

如何解决这个问题,为什么会这样?

以下是重现问题的一些代码:

视图(index.xhtml):

<h:body>
  <f:metadata>
    <f:viewParam name="vparam" value="#{index.vparam}" />
  </f:metadata>

  <comp:component />
</h:body>

managedBean(Index.java)

@ManagedBean(name="index")
public class Index implements Serializable {
    private String vparam;

    public void setVparam(String vparam) {
        this.vparam = vparam;
    }

    public String getVparam() {
        return vparam;
    }
}

组件视图(component.xhtml):

<h:body>
    <composite:interface componentType="component" />
    <composite:implementation>
        <f:metadata>
            <f:event type="preRenderComponent" listener="#{cc.generateString}" />
        </f:metadata>
        <h:outputText value="#{cc.string}" />
    </composite:implementation>
</h:body>

组件的java类(Component.java):

@FacesComponent(value="component")
public class Component extends UINamingContainer implements Serializable {
    private String string;

    public void generateString(){
        System.out.println("*** PRE RENDERING COMPONENT...");
        System.out.flush();
        string = "It worked!";
    }

    public String getString(){
        return string;
    }
}

此代码的预期输出为:字符串“It working!”打印在索引页面中。 实际输出是:nothing,因为空字符串由h:outputText打印为“”。

在日志文件中,“ * ** PRE RENDERING COMPONENT ...”未打印,从未执行过。

如果我从index.xhtml中删除以下行,一切正常:

<f:viewParam name="vparam" value="#{index.vparam}" />

为什么组件的父页面中存在“viewParam”会使JSF忽略组件中的“f:event”?

提前感谢您的回答。

1 个答案:

答案 0 :(得分:2)

根据the <f:metadata> documentation,视图可以只有一个 <f:metadata>,需要进入模板客户端(顶级XHTML页面,在HTTP请求时打开。

复合材料中的<f:metadata>被取代。它不属于那里。摆脱它。 <f:event>本身不需要放在<f:metadata>内。这是有意的:

<composite:implementation>
    <f:event type="preRenderComponent" listener="#{cc.generateString}" />
    ...
</composite:implementation>

导致您的具体问题,因为第二个<f:metadata>被完全忽略,包括其所有子女。

是的,你看到了很多<f:metadata><f:viewParam><f:event type="preRenderView">个例子,但<f:event>在这个特定情况下实际上是一种解决方法,仅用于放置在同一个{{1}内的自我纪录目的}作为它需要使用的<f:metadata>。在JSF 2.2中,以<f:viewParam>的风格引入了正确的方法。另请参阅What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?