【问题标题】:What scope to use in JSF 2.0 for Wizard pattern?在 JSF 2.0 中用于向导模式的范围是什么?
【发布时间】:2012-04-11 09:55:54
【问题描述】:

我有一个多页表单,也就是向导模式,其中第 1 页对应于向导表单的第 1 步,第 2 页对应于第 2 步,依此类推。除最后一页外,每个页面上都有一个“下一步”按钮带您到表单中的下一页。最后一页有一个提交按钮,用于提交向导中所有页面的所有数据。

我应该使用什么范围来维护在每个表单上输入的数据的状态?例如我应该使用一个 View Scoped bean 来保存在所有页面上输入的所有数据吗?这会起作用吗,因为我将导航到不同的页面(我相信它们被认为是不同的“视图”;如果它们是不同的视图,我相信当您导航到下一页时,View Scoped 数据将丢失向导)

【问题讨论】:

  • 我认为 ViewScope 仅适用于 Ajax。但我会推荐这个选项。

标签: jsf-2


【解决方案1】:

我相信当您导航到向导中的下一页时,View Scoped 数据会丢失)

没错。只要您与同一个视图交互并且每当创建新视图时都会被丢弃,视图范围就存在。您正在寻找“对话范围”。这在任何 JSF 托管 bean 范围内都不可用。然而,这可通过 CDI @ConversationScoped 获得。因此,如果您的环境恰好支持 CDI,您可以使用它:

import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@ConversationScoped
public class Wizard implements Serializable {

    @Inject
    private Conversation conversation;

    @PostConstruct
    public void init() {
        conversation.begin();
    }

    public void submitFirstStep() {
        // ...
    }

    // ...

    public String submitLastStep() {
        // ...

        conversation.end();
        return "someOtherPage?faces-redirect=true";
    }

    // ...
}

对话由自动插入的cid请求参数管理。

如果您想坚持 JSF 视图范围,那么最好的办法是创建一个页面,在其中有条件地呈现多个步骤:

<h:panelGroup rendered="#{wizard.step == 1}">
   <ui:include src="/WEB-INF/wizard/step1.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{wizard.step == 2}">
   <ui:include src="/WEB-INF/wizard/step2.xhtml" />
</h:panelGroup>
<h:panelGroup rendered="#{wizard.step == 3}">
   <ui:include src="/WEB-INF/wizard/step3.xhtml" />
</h:panelGroup>

或者,您可以使用第 3 方组件库,例如 PrimeFaces,它有一个 &lt;p:wizard&gt; 组件来实现此目的。

【讨论】:

  • 很遗憾,我无法访问 CDI 容器。我想我可能会选择 p:wizard 或条件渲染。使用 JSF 2.0 的“自定义范围”工具会提供另一种选择吗?
  • 是的,使用自定义 JSF2 范围肯定可以。它不会是一些我可以从头顶输入的微不足道的代码(只是因为我从来没有这样尝试过:))。
  • @BalusC 如何用它制作正确的 facelet 组合?它导致对我来说双重包含..一个来自这个panelGroups的页面..另一个来自特定步骤页面..现在步骤和panelGroups页面都有ui:composition标签,我想这就是问题..当我尝试从步骤页面中删除 ui:composition 标签,得到 xhtml 错误。我在这里检查了其他主题,但它们总是只显示这个 panelGroup 片段,而不是整个 html 页面代码,这样我就可以看到我缺少什么......并且找不到一个完整页面的示例。
【解决方案2】:

从我的观点来看,这里不错的选择是会话范围的 bean。需要时,用户将能够中断向导,访问其他页面、文档、手册等,然后返回到相同的向导步骤。当然,它可以通过视图范围的 bean 来完成(参见 BalusC 的答案)。当大量涉及 ajax 时,我个人更喜欢视图范围的 bean。在这种情况下,我建议将这两个范围结合起来。

【讨论】:

  • 我不会为此推荐会话范围。这将导致在多个浏览器窗口/选项卡中打开向导页面时出现异常。
  • @BestPractices,当然,这取决于。有些情况下ALT-F4也有问题,你不能到处赢))
【解决方案3】:

您可以在此站点找到使用会话范围创建向导的示例:

JEE6 – CDI and Conversation Scope

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-01
    • 2012-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 2012-08-15
    相关资源
    最近更新 更多