【问题标题】:"preRenderComponent" is ignored when "viewParam" is present in parent view当父视图中存在“viewParam”时,忽略“preRenderComponent”
【发布时间】:2013-06-25 07:43:15
【问题描述】:

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

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

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

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

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

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

提前感谢您的任何回答。

【问题讨论】:

    标签: jsf metadata composite-component


    【解决方案1】:

    根据the &lt;f:metadata&gt; documentation,视图可以有只有一个 &lt;f:metadata&gt;,需要进入模板客户端(打开的顶级XHTML页面HTTP 请求)。

    组合中的&lt;f:metadata&gt; 被替换。它不属于那里。摆脱它。 &lt;f:event&gt; 本身不需要放在&lt;f:metadata&gt; 中。这按预期工作:

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

    您的具体问题是因为第二个 &lt;f:metadata&gt; 被完全忽略,包括它的所有子级。

    的确,您看到了很多 &lt;f:metadata&gt;&lt;f:viewParam&gt;&lt;f:event type="preRenderView"&gt; 示例,但在这种特定情况下,&lt;f:event&gt; 实际上是一种解决方法,仅用于自我记录目的,放置在与 &lt;f:metadata&gt; 相同的 &lt;f:metadata&gt; 中s 它需要使用。在 JSF 2.2 中,以&lt;f:viewAction&gt; 的风格引入了正确的方式。另见What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?

    【讨论】:

    • 非常感谢您的回答!因为我现在不打算升级到 JSF 2.2,所以我在 f:metadata 之外使用了 f:event,它现在工作正常;)
    猜你喜欢
    • 2017-05-25
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多