JSF 2.0:如何在重定向后保存视图(target =空白) [英] JSF 2.0: how to save the view after redirect (target=blank)

查看:109
本文介绍了JSF 2.0:如何在重定向后保存视图(target =空白)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下,我有jsf表单和用于在表单数据上打印报告的按钮.该按钮需要在新页面上打开数据( target = blank ),但是 h:button 不适合我需要在报表之前保存数据页面打开.因此,我使用 h:commandButton 进行保存操作,然后重定向到报告页面:

Imagine I have the jsf form and the button to print report on form data. The button needs to open the data on the new page (target=blank), but h:button doesn't suit as I need to save the data just before the report page open. So, I use h:commandButton which makes the save action, and then redirects to the report page:

<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>

该实体已完美保存,并且新页面随报告一起打开.好的.但是,当我返回到初始表单页面并尝试再次保存时,该视图已过期并由new构建(因为这不是回发请求,因此这是对JSF的全新请求,因为我只是从此处进行了重定向页!).尽管重定向是在打开第二页时完成的,但这并不能防止丢失所有视图作用域的bean数据.

The entity is saved perfectly and the new page is open with the report. Good. But when I go back to the initial form page and try to save again - the view is expired and built by new (as this is not a postback request, this is a totally new request for JSF, because I just made the redirect from this page!). Although the redirect was done while opening second page, this doesn't prevent from loosing all view scoped bean data..

我尝试了从CDI长期运行的 conversationScope ,但是当我返回时,它抛出了"ContextNotActiveException:WELD-001303范围类型javax.enterprise.context.ConversationScoped没有活动的上下文"的异常.初始页面...

I tried the long-running conversationScope from CDI, but it throws the "ContextNotActiveException: WELD-001303 No active contexts for scope type javax.enterprise.context.ConversationScoped" exception when I turn back to the initial page...

有人解决了这个问题吗?如何通过重定向(到新页面)提交表单,但又不丢失初始数据?

Has anyone solved the problem? How can I do the form submit with the redirect (to new page) but not loose the initial data?

推荐答案

如果有人感兴趣,我找到了解决方法.不是很漂亮,但是可以使用重定向到空白"页面的方法:

If anyone is interested, I found the workaround. Not very beautiful, but allows to work with redirects to "blank" pages:

收据用于在新窗口中打开链接后刷新初始页面(请参见 onclick ):

The receipt is to do the refresh of the initial page just after the link was opened in new window (see 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 参数的以下地址刷新页面:

But that's not as simple as it seems to be, I cannot use the simple location.reload() or smth similar. In the doReportPrint() method I do the save operation and if the entity does not exist, it is created. As I use GET-parametrized request for my application, I will need to refresh page using the following address with id parameter:

/polises/polis.jsf?id=80

因此,需要完成新的jsf请求,而不是简单的JS刷新(其中包含新创建的实体的ID).所以我使用这种方法:

So, the the new jsf request needs to be done, not a simple JS refresh, which contains the id of newly created entity. So I use this approach:

doReportPrint 中,我将新创建的ID保存到会话中:

In doReportPrint I save the newly created id to the session:

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

通过以下方式刷新初始页面:

And the refresh of the initial page is done the following way:

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重新打开(使用Faces-Config导航),并且ID自动从 entity.id 附加

Save outcome results in polis.jsf reopen (using faces-config navigation) and the id is attached from entity.id automatically

另一个技巧是如何从JS调用JSF动作.我试图模仿 h:commandLink 单击(只是复制了链接的生成的JS代码),但这没有用,因为重新创建了视图,并且bean及其属性也是如此,只是操作没有被打.因此,我使用了PrimeFaces p:commandLink 的JS代码,它对我来说非常有用(不要忘记将"update"设置为@none并将"process"设置为@this):

Another trick is how to call the JSF action from JS. I tried to imitate h:commandLink click (just copied the generated JS code for the link), but this didn't work, as the view is recreated and the same for bean and its properties, actions simply wasn't called. So I used the JS code for PrimeFaces p:commandLink and it worked great for me (dont' forget to set "update" to @none and "process" to @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秒钟内将刷新初始页面.太丑陋,太累人了,但是对我有用.可能会帮助其他人.

So now the initial page is being refreshed in 2 seconds after the report being saved and opened in new windows. Too ugly and too burdensome, but it works for me. May be will help anyone else.

这篇关于JSF 2.0:如何在重定向后保存视图(target =空白)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆