1

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

一种方法是对事件“preRenderComponent”使用 f:metadata 和 f:event。它工作得很好,除非我在持有组件的视图中也有带有 f:viewParam 的 af:metadata。如果我在父视图中有 af: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 works!” 打印在索引页中。实际输出是:什么都没有,因为 h:outputText 将空字符串打印为“”。

在日志文件中,“ * ** PRE RENDERING COMPONENT...”没有打印出来,它永远不会被执行。

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

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

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

提前感谢您的任何回答。

4

1 回答 1

2

根据文档<f:metadata>视图只能有一个 <f:metadata>需要进入模板客户端(根据 HTTP 请求打开的顶级 XHTML 页面)。

复合材料中的<f:metadata>被置换。它不属于那里。摆脱它。dos<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>在这种特定情况下,实际上是一种解决方法,并且仅出于自我记录目的而放置在与它需要使用<f:metadata>的s 完全相同的内部。<f:viewParam>在 JSF 2.2 中,在<f:viewAction>. 另请参阅<f:metadata>、<f:viewParam> 和 <f:viewAction> 可以用于什么?

于 2013-06-27T17:23:19.057 回答