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

Ion*_*chy 10 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>
Run Code Online (Sandbox Code Playgroud)

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

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

非常感谢.

sku*_*sel 7

实际上你的问题是经典的视图构建与视图渲染时间问题/误解.更具体地说,视图建立在每个新请求上,并在回发时从先前保存的状态重建.稍后,视图将呈现为生成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>
Run Code Online (Sandbox Code Playgroud)