10

我在 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>

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

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

非常感谢帮助。

4

2 回答 2

8

实际上,您的问题是经典视图构建与视图渲染时间问题/误解。更具体地说,视图建立在每个新请求上,并从以前保存的回发状态重建。稍后渲染视图以生成 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>
于 2013-04-23T15:27:48.240 回答
1

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

<context-param> 
    <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> 
    <param-value>false</param-value>
</context-param>
于 2013-04-23T15:46:59.787 回答