在JSF 2.0 for Wizard模式中使用什么范围



我有一个多页表单,也称为向导模式,其中第1页对应于向导表单的第1步,第2页对应于第2步,等等。除最后一页外,每一页上都有一个"下一页"按钮,可将您带到表单的下一页。最后一页有一个提交按钮,可提交向导中所有页面的所有数据。

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

我相信当您导航到向导中的下一页时,查看范围数据将丢失)

这是正确的。只要您与同一视图交互,视图范围就会一直存在,并且每当创建新视图时就会被破坏。你正在寻找"对话范围"。这在任何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>

或者,您可以使用第三方组件库,如PrimeFaces,它具有完全用于此目的的<p:wizard>组件。

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

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

JEE6–CDI和会话范围

最新更新