<ui:include>与动态src ...完全疯狂</ui:include>

时间:2013-04-23 13:23:08

标签: jsf-2

我遇到了一个很大的问题,在JSF中完成了一个非常简单的任务。问题:我有一些对象,这些对象具有聚合属性,这些属性的类型可以在不同对象之间变化。根据属性的类型,我想使用一组不同的输入字段。

子类型组件驻留在框架中并按需加载。为此,我使用以下代码:

<h:panelGroup id="zusatzdaten">
    <fieldset class="clear">
    <legend>#{tickerUI.ticker.tickerDescription.label}
          (#{tickerUI.ticker.tickerDescId})
    </legend>
    <h:panelGroup rendered="#{tickerUI.editComponentName != null}">
        <ui:include src="#{tickerUI.editComponentName}"/>
    </h:panelGroup>
    </fieldset>
</h:panelGroup>

组件的名称来自TickerUI,它是@SessionScope。现在令人眼花缭乱的一点:首次加载时,会显示正确的子组件。但是,当在导航中使用链接时,应该导致包含不同的组件,内容不会更新!这会导致错误,因为数据现在是不同的子类型,但表单组件仍然来自前一个。

从错误返回并再次单击链接时,将显示正确的组件。我记录了editComponentName的值,并返回了正确的值。这非常令人困惑。当getter将正确的组件名称返回到src属性时,为什么包含错误的内容?

非常感谢。

2 个答案:

答案 0 :(得分:7)

实际上你的问题是经典的视图构建与视图渲染时间问题/误解。更具体地说,视图是在每个新请求上构建,并且在回发时从先前保存的状态重建。稍后视图呈现以生成HTML内容。

现在,由于<ui:include>标记处理程序,或者在官方术语中是视图构建时标记,当您第一次请求页面时,其{{1>} 1}}属性被评估,包含的页面进入视图。在回发时,与您所期望的相反,在重建的视图中,已经包含的内容已经存在。因此,预期的行为是,您将拥有呈现的视图的确切部分。

关于解决方案,您可以简单地包含一个包含在有条件呈现的value JSF组件中的静态包含的详尽列表。为简单起见,所有内容都可以放在像<ui:fragment>这样的容器中,以便于AJAX更新。代码可以按如下方式汇编:

<h:panelGroup>

答案 1 :(得分:1)

似乎是经典的两难困境。 BalusC's blog以web.xml中的配置参数的形式为我的案例提供了解决方案:

<context-param> 
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> 
    <param-value>false</param-value>
</context-param>