1

我有一个 JSF 2.0 facelets 视图,其中包含一个搜索表单、一个用于显示结果的 ui:repeat 和一个寻呼机。它由请求 bean 支持。表单帖子由当前页面和搜索条件组成。寻呼机显示下一页和上一页链接,具体取决于数据集中的位置,以及来自表单的搜索条件的查询结果数量。所以组件树依赖于请求属性。例如,我在这样的下一页链接上使用渲染属性

<h:commandLink action="#{listBean.nextPage}" rendered="#{listBean.hasNextPage}" >...

当用户单击此链接时,POST 请求包含当前页面和搜索条件。问题是,组件树已经在 RESTORE_VIEW 中构建。此时,由于尚未应用请求属性,我无法判断用户当前在哪个页面上,或者数据集中有多少条记录,因为我没有搜索条件。因此 listBean.hasNextPage 在此阶段的评估结果为 false。这似乎导致 CommandLink 从组件树中消失。在 APPLY_REQUEST_VALUES 之后,我可以构建我的计数查询。有了这些信息和当前页面,我可以计算 listBean.hasNextPage。但是,它似乎直到 RENDER_RESPONSE 才再次得到评估。该操作根本不会在 INVOKE_APPLICATION 中调用。也没有错误,这很烦人。

它在用 c:if 替换渲染时起作用。c:if 只在 RENDER_RESPONSE 中评估一次,默认情况下组件在第一阶段的树中。我真的不喜欢它,因为在(罕见的,承认的)情况下,数据集计数发生了变化,因此实际上没有下一页,它仍然会调用该操作并且用户将处于非法页面中。我也知道在 Facelets 中使用 JSTL 标记通常是不建议的。我不知道为什么。

是否有任何技巧可以将评估延迟到 APPLY_REQUEST_VALUES 之后?必须有一种方法可以在依赖于当前请求的属性上使用此属性。仅供参考,这是 Liferay 上带有 JBoss portlet 桥的 portlet 2.0 应用程序,但我想这是一个通用的 JSF 问题。

提前感谢您的任何答案。我希望我只是忽略了一些东西,我还在学习 JSF——我不会那么难写一个寻呼机,对吧:-)

4

1 回答 1

2

根据您的描述,您似乎认为在新请求(回发)开始时需要新数据集,但事实并非如此。

在您需要提供用于呈现用户刚刚单击的页面的数据集之前,而RESTORE_VIEW不是用于呈现当前请求的数据集。INVOKE_APPLICATION

实现这一点的最简单方法是创建支持 bean@ViewScoped并通过实例变量保存对数据集的引用。回发后,JSF 将自动保留“旧”数据集并将其用于生命周期的第一部分。然后INVOKE_APPLICATION你有所有数据来加载你的下一页,从而设置“新”数据集和布尔值hasNextPage

RENDER_RESPONSE然后将使用新值发生并呈现您的新页面。

于 2011-07-25T09:43:03.607 回答