Какую возможность использовать в JSF 2.0 для шаблона мастера?

У меня есть многостраничная форма, например шаблон мастера, где страница 1 соответствует шагу 1 формы мастера, страница соответствует шагу 2 и т.д. На каждой странице, кроме последней, есть кнопка "Далее", которая вы перейдете на следующую страницу в форме. На последней странице есть кнопка отправки, которая отправляет все данные для всех страниц в мастере.

Какую область действия я должен использовать для поддержания состояния данных, введенных в каждой форме? например следует ли использовать View Scoped bean, который содержит все данные, введенные на всех страницах? Будет ли это работать с тех пор, как я буду перемещаться по разным страницам (которые, как я считаю, считаются разными "представлениями", и если они отличаются друг от друга, я считаю, что данные View Scoped будут потеряны при переходе на следующую страницу в мастер)

Ответ 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>

Или вы могли бы использовать стороннюю библиотеку компонентов, например PrimeFaces, которая имеет <p:wizard> для этой цели.

Ответ 2

Из моего pov, хороший выбор здесь - это сеансовый охват beans. При необходимости пользователь сможет прервать работу мастера, посетить другие страницы, документы, руководства и т.д. И вернуться к тому же мастер-шагу. Конечно, это можно сделать с помощью beans с просмотром (см. Ответ BalusC). Лично я предпочитаю view-scoped beans, когда ajax сильно вовлечен. В этом случае я бы рекомендовал объединить эти две области.