JSF 2.0页面,在两个页面之间导航而不会丢失数据

时间:2017-12-26 12:08:49

标签: jsf redirect primefaces

我有以下问题: 我有一个页面,我在其中创建了一个报价( page1 )。 现在我在第1页上有一个按钮来选择客户(第2页)。

所以我按下按钮,我的新页面(第2页)似乎选择了一个客户。 使用另一个按钮,我选择客户并重定向到我的第一页(报价页面)。但现在我输入的所有值都不存在了。

我尝试了以下内容:

import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.SessionScoped;
import javax.faces.view.ViewScoped;

我的按钮如下:

                    <p:commandButton value="Select customer" ajax="true" process="@all"
                                        actionListener="#{offerEditController.doSelectCustomerForDocument}"
                                        update=":addOfferForm, growl" immediate="true">
                                    </p:commandButton>

这是我的方法,转到第2页:

    public void doSelectCustomerForDocument()  {

    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.redirect(ec.getRequestContextPath() + Constants.CUSTOMER_LIST
            + "?create_document=/offerEdit.jsf&document_id=" + offer.getId());
}

@SessionScoped不适用于所有inputField,例如

有关

<p:inputText id="offer_subject"
                                            value="#{offerEditController.offer.title}" >
                                            <p:ajax events="blur" update="offer_subject_panel"
                                                global="false" />
                                        </p:inputText>

任何想法如何解决这个问题?我知道我可以使用p:对话框,但我不喜欢这个。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

更好的ideia会使用p:对话框,因为它完全适合您的情况但如果您不喜欢它,您应该改进调用页面的方式。在您的情况下,当您执行以下操作时:

ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.redirect(ec.getRequestContextPath() + Constants.CUSTOMER_LIST
        + "?create_document=/offerEdit.jsf&document_id=" + offer.getId())

你强制页面重新加载并调用@PostConstruct方法,清理整个支持bean(控制器)。这就是你输入值的原因。

如果要保留这种重定向方法,则必须在清理之前将页面数据存储在某处。我建议使用<p:remoteCommand>在requestContext中使用JSON从page2到page1传递参数,然后,当你重新加载@PostConstruct方法时,你在requestContext中查找参数并重置字段。

把它放在第2页:

<p:commandButton id="buttonOnPage2" onclick = "remoteCommandFunction([{name:'value1',value:'#{bean.value1}'},{name:'value2',value:'#{bean.value2}'}])"/>

<p:remoteCommand name="remoteCommandFunction" actionListener="#{bean.storeData()}"/>

在你的bean上:

public void storeData(){
    Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
    if(params.get("value1") !=null && !params.get("value1").isEmpty())
        this.value1= params.get("value1");
    if(params.get("value2") !=null && !params.get("value2").isEmpty())
        this.value2= params.get("value2");  
}

你必须确保在@PostConstruct之后调用storeData()方法,如果在post构造之后调用它,一切都将为null。如果发生这种情况,您应该将storeData()方法放在@SessionScoped bean中,并在@ViewScoped内部@PostConstruct方法中检索它,如下所示:

@PostConstruct
   public void init(){
   ...
   this.value1 = getSessionScopedBean().getValue1();
   this.value2 = getSessionScopedBean().getValue2();

   getSessionScopedBean().setValue1(null);
   getSessionScopedBean().setValue2(null);
}