<ui:include> with dynamic src ...完全的疯狂



我在用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属性?

非常感谢。

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

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

对于解决方案,您可以简单地包含一个详尽的静态包含列表,这些包含被包装在有条件呈现的<ui:fragment> JSF组件中。为简单起见,所有内容都可以放在像<h:panelGroup>这样的容器中,这种容器总是为了方便AJAX更新而呈现。代码可以按照如下方式组装:

<h:panelGroup id="ui">
    <ui:fragment rendered="#{bean.condition1}">
        <ui:include src="/path/to/file1.xhtml"/>
    </ui:fragment>
    ...
    <ui:fragment rendered="#{bean.condition_n}">
        <ui:include src="/path/to/file_n.xhtml"/>
    </ui:fragment>
</h:panelGroup>

这似乎是一个经典的困境。BalusC的博客以web.xml中的配置参数的形式给出了我的解决方案:

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

最新更新