ui:include依赖于viewParam

4

我有一个页面,想根据视图参数的值包含页面的一部分(在这种情况下是页脚)。

我有一个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>

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

我理解这与JSF的阶段有关,在完成 ui:include 时,该值尚未设置。(阅读并更好地了解各个阶段是我的待办事项之一)。

问题仍然存在。如何完成类似的操作。让一个bean使用 viewParam,查询数据库并在 ui:include 中使用该值?

2个回答

3

@wemu已经解释了原因。在调用init()方法之前,<ui:include src>已经被计算出来了。他提出的<f:phaseListener>解决方案非常笨重。

只需在一个@RequestScoped bean上使用@ManagedProperty/@PostConstruct即可。

@ManagedProperty("#{param.racecode}")
private String racecode;

@PostConstruct
public void init() {
    // ...
}

这非常有道理。我经常担心最佳实践以及类似的事情(我想我有点强迫症)。现在假设我要为此页面加载两个bean,并且这会创建对数据库的额外调用。当然,我有需要使其工作的信息。是否更好地将当前的preRenderView完全更改为这个,将所有内容放在一个位置?另外,这里为什么是@RequestScoped - blo0p3r
2
你可以通过@ManagedProperty在彼此之间注入bean。@RequestScoped是强制性的,原因有两个:1)#{param}是请求作用域 2)<ui:include>是一个taghandler。所以@ViewScope绝对不是一个选项。 - BalusC
这对于我想做的事情确实有效。但似乎导致了另一个问题。我在同一页上拥有我的请求作用域和视图作用域bean。当我在页面上触发一个应该调用我的ViewScope bean中的方法的actionListener时,它只调用请求作用域bean,永远不会到达相关方法。 - blo0p3r
在使用动态包含时,与表单结合使用确实存在问题。有关详细信息,请参见此问题+答案:https://dev59.com/R2gu5IYBdhLWcg3wUlnt - BalusC
类似的问题,但是解决方案没有起作用。我现在将相同的“displayResults”设置为“viewScoped”,并且设置了一个新的“requestScoped”自定义结果。这个customResults获取我的包含信息并正常工作。但是当我在页面中点击监听器时,它只调用了“customResults”的构造函数,而不是由操作调用的“displayResults”方法。 - blo0p3r

1

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

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

如果您需要这样做,请使用<f:phaseListener>


我理解你的意思。但是根据这个链接,我需要通过preRenderView来处理,因为myViewId依赖于viewParam-->所以我仍然需要“等待”更新模型值阶段? - blo0p3r
是的,我也这么认为,但要让我相信它,我需要尝试一下(这种东西让我感到困惑)。 - wemu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接