【问题标题】:ui:include dependent on viewParamui:include 依赖于 viewParam
【发布时间】:2012-09-25 14:14:46
【问题描述】:

我有一个页面,我想根据视图参数给出的值包含页面的一部分(在本例中为页脚)。

我的 ViewScoped 支持 bean 在 preRenderView 上初始化

<f:metadata>
    <f:viewParam name="racecode" value="#{displayResults.racecode}" />
    <f:event type="preRenderView" listener="#{displayResults.init}" />  
</f:metadata>

这会查询数据库以获取要包含的页脚的名称。然后,以这种方式使用它:

<h:panelGroup id="customFooter" display="block">
    <ui:include src="#{displayResults.customFooter}" />
</h:panelGroup>

这总是给我一个缺失的页面。但是,如果我手动输入页面名称,它就可以工作。如果我将 ui:include 替换为 h:outputText,则相同。

我知道这与 JSF 的阶段有关,并且在 ui:include 完成时,该值尚未设置。 (阅读和更好地理解这些阶段是我的 TODO 清单上的内容)。

问题仍然存在。我怎样才能完成这样的事情。让 bean 使用 viewParam,查询数据库并在 ui:include 中使用该值?

【问题讨论】:

    标签: java jsf jsf-2 viewparams


    【解决方案1】:

    @wemu 已经解释了原因。 &lt;ui:include src&gt; 在调用 init() 方法之前进行评估。然而,他提出的&lt;f:phaseListener&gt; 解决方案很笨拙。

    只需在 @RequestScoped bean 上使用 @ManagedProperty/@PostConstruct

    @ManagedProperty("#{param.racecode}")
    private String racecode;
    
    @PostConstruct
    public void init() {
        // ...
    }
    

    【讨论】:

    • 这完全有道理。我经常关心最佳实践和类似的东西(我认为有点强迫症)。现在假设我正在为这一页面加载加载两个 bean,这会创建对数据库的额外调用。当然,我有完成这项工作所需的信息。将我当前的preRenderView 完全更改为此并将所有内容集中在一个位置会更好吗?另外,为什么在这里@RequestScoped
    • 您可以通过@ManagedProperty 相互注入bean。 @RequestScoped 是强制性的,原因有两个:1) #{param} 是请求范围的 2) &lt;ui:include&gt;taghandler。所以@ViewScope 绝对不是一个选择。
    • 这确实为我想做的事情工作。但似乎已经让到另一个问题。我的 resquest 范围和视图范围 bean 都在同一页面上。当我在我的页面上触发一个应该触发我的 viewScope bean 中的方法的 actionListener 时,它只会调用请求范围 bean,而不会将它用于相关方法。
    • 在将表单与动态包含结合使用方面确实存在问题。有关详细信息,请参阅此问题+答案:stackoverflow.com/questions/11408130/…
    • 类似问题,但解决方法无效。我现在将相同的displayResults 设置为viewScoped,并将新的customResults 设置为requestScoped。此 customResults 获取我包含的信息并且工作正常。但是当我在页面中单击一个侦听器时,它所做的只是将构造函数调用到 customResults,而不是方法调用 displayResults 方法。
    【解决方案2】:

    PreRenderView 侦听器在 RenderResponsePhase 中调用,在渲染组件之前,但在调用 TagHandlers 之后。这意味着 TagHandlers 不会看到在 PreRenderView 事件中初始化的数据。

    如果您使用 &lt;ui:include value="#{myBean.myViewId}" /&gt; 动态切换包含,则不能使用 PreRenderView 事件侦听器来设置 myBeanmyViewId 属性。

    如果您需要这样做,请使用&lt;f:phaseListener&gt;

    【讨论】:

    • 我明白你在说什么。但据我了解并根据this link 我需要通过preRenderView 因为myViewId 依赖于viewParam --> 所以我仍然需要“等待”直到更新模型值阶段?
    • 是的,我也这么认为,但要自己相信,我需要尝试一下(这样的事情让我感到困惑)。
    猜你喜欢
    • 2012-07-06
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 2020-04-06
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    相关资源
    最近更新 更多