JSF 2.0: как сохранить представление после перенаправления (target = blank) - PullRequest
2 голосов
/ 25 марта 2011

Представьте, что у меня есть форма jsf и кнопка для печати отчета по данным формы. Кнопка должна открыть данные на новой странице ( target = blank ), но h: кнопка не подходит, так как мне нужно сохранить данные непосредственно перед открытием страницы отчета. , Итак, я использую h: commandButton , который выполняет действие сохранения, а затем перенаправляет на страницу отчета:

<h:commandLink styleClass="reportButton" action="#{polisBean.doReportPrint}"
                    target="_blank" id="reportListLink">
                    Print report
                </h:commandLink>

@ViewScoped
@Named
public class PolisBean
  ...
  public Object doReportPrint() {        
    if (canEdit() && this.submit() == null) {
        return null;
    }

    return "printReport";
}
<navigation-case>
        <from-outcome>printReport</from-outcome>
        <to-view-id>/polises/reportList.xhtml</to-view-id>
        <redirect include-view-params="true">
            <view-param>
                <name>id</name>
                <value>#{polis.id}</value>
            </view-param>
        </redirect>
    </navigation-case>

Объект сохраняется отлично, и открывается новая страница с отчетом. Хорошо. Но когда я возвращаюсь на начальную страницу формы и пытаюсь сохранить снова - представление истекло и построено новым (так как это не запрос обратной передачи, это совершенно новый запрос для JSF, потому что я только что сделал перенаправление из этой страница!). Хотя перенаправление было выполнено при открытии второй страницы, это не предотвращает потерю всех данных bean-объекта видимости ..

Я попытался запустить долгосрочный разговорScope из CDI, но он выдает исключение «ContextNotActiveException: WELD-001303 Нет активных контекстов для типа области действия javax.enterprise.context.ConversationScoped», когда я возвращаюсь к начальная страница ...

Кто-нибудь решил проблему? Как я могу отправить форму с перенаправлением (на новую страницу), но не потерять исходные данные?

Ответы [ 2 ]

2 голосов
/ 26 марта 2011

Если кому-то интересно, я нашел обходной путь. Не очень красиво, но позволяет работать с перенаправлениями на «пустые» страницы:

Квитанция должна выполнить обновление начальной страницы сразу после открытия ссылки в новом окне (см. onclick ):

<h:commandLink styleClass="reportButton" action="#{polisBean.doReportPrint()}" onclick="window.setTimeout(refreshPage, 2000)"
                    target="_blank" id="reportListLink" >
                    print report
                </h:commandLink>

Но это не так просто, как кажется, я не могу использовать простой location.reload () или что-то подобное. В методе doReportPrint () я выполняю операцию сохранения, и если объект не существует, он создается. Поскольку я использую GET-параметризованный запрос для своего приложения, мне нужно будет обновить страницу, используя следующий адрес с параметром id :

/polises/polis.jsf?id=80

Итак, необходимо выполнить новый запрос jsf, а не простое обновление JS, которое содержит идентификатор вновь созданного объекта. Поэтому я использую этот подход:

В doReportPrint Я сохраняю вновь созданный идентификатор в сеансе:

public Object doReportPrint() {        
    if (canEdit() && this.submit() == null) {
        return null;
    }
    context().getExternalContext().getSessionMap().put("justUpdatedPolisId", entity.getId());        
    return "printReport";
}

И обновление начальной страницы выполняется следующим образом:

public Object doRefresh() {
    Object justUpdatedPolisId = context().getExternalContext().getSessionMap().get("justUpdatedPolisId");
    if (justUpdatedPolisId != null) {
        entity.setId((Long)justUpdatedPolisId);
        context().getExternalContext().getSessionMap().remove("justUpdatedPolisId");
        return "save";
    }
    // If for some reasons we have not found it - moving to polises table
    return "polises?faces-redirect=true";
}

Сохранение результатов приводит к повторному открытию polis.jsf (с использованием навигации лица-конфигурации), и идентификатор присоединяется из entity.id автоматически

Еще одна хитрость - как вызвать действие JSF из JS. Я пытался имитировать h: commandLink click (просто скопировал сгенерированный код JS для ссылки), но это не сработало, так как представление воссоздается и то же самое для bean-компонента и его свойств, действия просто не выполнялись не звонил. Поэтому я использовал код JS для PrimeFaces p: commandLink , и он отлично работал для меня (не забудьте установить для «update» значение @none и для «process» значение @this):

<script type="text/javascript"> 
   function refreshPage() {
                        PrimeFaces.ajax.AjaxRequest('/KaskoCalculator/polises/polis.jsf',{formId:'polisForm',async:false,global:true,source:'polisForm:doRefresh',process:'polisForm:doRefresh',update:'@none'});
                        }
   </script>

Итак, начальная страница обновляется через 2 секунды после сохранения и открытия отчета в новых окнах. Слишком некрасиво и обременительно, но у меня это работает. Может быть, поможет кому-нибудь еще.

0 голосов
/ 24 февраля 2013

Я столкнулся с той же проблемой.При использовании p: commandLink или h: commandLink с target = _blank начальные данные компонента поддержки страницы исчезают после открытия нового окна.

Обновление вернется к исходному состоянию страницы без обновлений ajax.но мне нужно сохранить то же состояние, прежде чем щелкнуть команду печати. ​​

...