JSF2.0 Ajax 导航模式

发布于 2024-12-10 00:55:12 字数 4032 浏览 1 评论 0原文

非常感谢有关使用 JSF 2.0、PrimeFaces 和 Ajax 的 Web 应用程序模式的一些指导。我们当前的系统使用具有标准提交的 JSP,并且我们的应用程序中的每个功能页面都有 1 个 JSP。每个 JSP 都调用一个操作类来进行逻辑、导航和 EJB 调用。使用相同的设置迁移到 JSF 会相对简单,即 1 个 xhtml 页面和关联的支持 bean 以及通过 do 方法完成的导航/逻辑。然而我们想通过 Ajax 提交,这给我带来了困惑。如果我加载 abc1.xhtml 并使用 ajax 提交,那么我会保留在 abc1.xhtml 上,尽管我可能需要转到 abc2.xhtml。我考虑过在 1 个 xhtml 页面上放置关联的表单,并使用渲染的属性来决定要显示的内容。这可行,但我不舒服在一页中有很多表格。理想情况下,我想将每个页面分开,但不知道如何使用 Ajax 实现这一点。任何想法将不胜感激。

编辑 - 这是原始的解决方案,但现在已在下面的答案中进行了改进。这可行,但参数似乎存在问题。当我单击 AAA 或 BBB 链接时,我需要传递一个参数,以便 ViewController bean 知道单击了什么以及在何处设置目标页面。但是,如果我单击 AAA.xhtml 中的“提交”按钮,内容不会更改,除非我还将 添加到命令按钮。我以为我已经在 ViewController 构造函数中处理了 null Param,但显然我错过了一些重要的东西。我唯一的想法就是与 URL 有关。当我单击菜单链接时,它会将参数添加到 url ?tranID=AAA 上。如果我不将参数添加到后续提交中,这是否会有效地更改 url 并导致某种不匹配?

viewController.xhtml

<h:body>
    <h:panelGroup layout="block" id="transactionControl">

                    <h4>
                        <h:outputLink id="mfa" value="#{facesContext.externalContext.requestContextPath}/xhtml/viewController.xhtml" styleClass="menuLink">
                            <h:outputText value="AAA"></h:outputText>
                            <f:param name="tranID" value="AAA"/>
                        </h:outputLink>
                    </h4>

                    <h4>
                        <h:outputLink id="inq" value="#{facesContext.externalContext.requestContextPath}/xhtml/viewController.xhtml" styleClass="menuLink">
                            <h:outputText value="BBB"></h:outputText>
                            <f:param name="tranID" value="BBB"/>
                        </h:outputLink>
                    </h4>



    </h:panelGroup>

    <h:panelGroup layout="block" id="content" style="border-style: solid;">

        <ui:include src="#{viewController.destinationPage}.xhtml"></ui:include>

    </h:panelGroup>

</h:body>

AAA.xhtml

<h:body>
    <h:form prependId="false">
        <h:outputText value="Click the button to go to AAB"></h:outputText>

        <p>
            <p:commandButton id="submitButton" value="Go" ajax="true" actionListener="#{viewController.doAAAtoAAB}"
                             process="@form"
                             update="content">
                <f:param name="tranID" value="AAA"/>
            </p:commandButton>
        </p>

    </h:form>

</h:body>

AAB.xhtml >

<h:body>
    <h:panelGroup layout="block" id="subContent">
        <h:outputText value="This is the AAB content"></h:outputText>
    </h:panelGroup>
</h:body>

BBB.xhtml 和 BBC.xhtml 如上

ViewController bean

package com.mcpplc.supportclient.webapp.managedBeans;


import javax.faces.context.FacesContext;    
import java.io.Serializable;

@ManagedBean
@ViewScoped
public class ViewController implements Serializable
{
    String destinationPage = "splash";
    FacesContext context;
    String callingTranID;

    public ViewController ()
    {
        context = FacesContext.getCurrentInstance();
        callingTranID = context.getExternalContext().getRequestParameterMap().get("tranID");

        if (callingTranID != null )
        {
            destinationPage = callingTranID;
        }
    }


    public void doAAAtoAAB()
    {
         destinationPage = "AAB";
    }

    public void doBBBtoBBC()
    {
         destinationPage = "BBC";
    }

    public String getDestinationPage()
    {
        return destinationPage;
    }

    public void setDestinationPage( String destinationPage )
    {
        this.destinationPage = destinationPage;
    }
}

Would really appreciate some guidance concerning patterns for a Web App using JSF 2.0, PrimeFaces and Ajax. Our current system uses JSPs with standard submits and we have 1 JSP for each functional page in our app. Each JSP calls an action class for logic, navigation and EJB calls. Migrating to JSF using the same set up would be relatively simple i.e. 1 xhtml page and associated backing bean and navigation/logic done via a do method. However we want to submit via Ajax and this causes puzzles in my head. If I load abc1.xhtml and submit with ajax then I stay on abc1.xhtml although I might need to go to abc2.xhtml. I thought about having the associated forms on 1 xhtml page and using the rendered property to decide what to display. This works but I'm not comfortable having lots of forms in 1 page. Ideally I want to keep each page separate but don't know how this is possible with Ajax. Any ideas would be much appreciated.

Edit - This was original Solution but now has been refined in my answer below. This works but there seems to be issues with the Params. When I click on the AAA or BBB link I need to pass a param so that the ViewController bean knows what was clicked and where to set the Destination page. However if I click the Submit button in AAA.xhtml the content doesn't change unless I also add <f:param name="tranID" value="AAA"/> to the command button. I'd thought I'd handled a null Param in the ViewController constructor but obviously I'm missing something important. My only thoughts were to do with the URL. When I click the menu link it adds the param on to the url ?tranID=AAA. If I then don't add the param onto the subsequent submit is this effectively changing the url and causing some sort of mismatch?

viewController.xhtml

<h:body>
    <h:panelGroup layout="block" id="transactionControl">

                    <h4>
                        <h:outputLink id="mfa" value="#{facesContext.externalContext.requestContextPath}/xhtml/viewController.xhtml" styleClass="menuLink">
                            <h:outputText value="AAA"></h:outputText>
                            <f:param name="tranID" value="AAA"/>
                        </h:outputLink>
                    </h4>

                    <h4>
                        <h:outputLink id="inq" value="#{facesContext.externalContext.requestContextPath}/xhtml/viewController.xhtml" styleClass="menuLink">
                            <h:outputText value="BBB"></h:outputText>
                            <f:param name="tranID" value="BBB"/>
                        </h:outputLink>
                    </h4>



    </h:panelGroup>

    <h:panelGroup layout="block" id="content" style="border-style: solid;">

        <ui:include src="#{viewController.destinationPage}.xhtml"></ui:include>

    </h:panelGroup>

</h:body>

AAA.xhtml

<h:body>
    <h:form prependId="false">
        <h:outputText value="Click the button to go to AAB"></h:outputText>

        <p>
            <p:commandButton id="submitButton" value="Go" ajax="true" actionListener="#{viewController.doAAAtoAAB}"
                             process="@form"
                             update="content">
                <f:param name="tranID" value="AAA"/>
            </p:commandButton>
        </p>

    </h:form>

</h:body>

AAB.xhtml

<h:body>
    <h:panelGroup layout="block" id="subContent">
        <h:outputText value="This is the AAB content"></h:outputText>
    </h:panelGroup>
</h:body>

BBB.xhtml and BBC.xhtml as above

ViewController bean

package com.mcpplc.supportclient.webapp.managedBeans;


import javax.faces.context.FacesContext;    
import java.io.Serializable;

@ManagedBean
@ViewScoped
public class ViewController implements Serializable
{
    String destinationPage = "splash";
    FacesContext context;
    String callingTranID;

    public ViewController ()
    {
        context = FacesContext.getCurrentInstance();
        callingTranID = context.getExternalContext().getRequestParameterMap().get("tranID");

        if (callingTranID != null )
        {
            destinationPage = callingTranID;
        }
    }


    public void doAAAtoAAB()
    {
         destinationPage = "AAB";
    }

    public void doBBBtoBBC()
    {
         destinationPage = "BBC";
    }

    public String getDestinationPage()
    {
        return destinationPage;
    }

    public void setDestinationPage( String destinationPage )
    {
        this.destinationPage = destinationPage;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

演多会厌 2024-12-17 00:55:12

我对你的建议是,除非你需要,否则不要使用ajax。如果您需要在请求后实际调用另一个页面,那么使用ajax有什么意义呢?

尝试考虑应用程序工作流程并在必要时应用 ajax。您认为 ajax 会令人困惑的情况是因为您可能不应该使用它

干杯

My recomendation for you is, do not use ajax unless you need it. If you need to actually call another page after a request, what is the point in using ajax?

Try to think in the application workflow and apply ajax where it is necessary. The cases you think that ajax will be confusing, is because you probably should not be using it

Cheers

策马西风 2024-12-17 00:55:12

决定回答我自己的问题,因为我现在已经有了一个完整的、仅支持 ajax 的原型应用程序。这符合我最初的要求,即将每个视图保存为一个 .xhtml 页面,并且每个视图都有自己的支持 bean。这里没有进一步污染我的问题,而是简化的代码。 (感谢 BalusC 之前的回答,虽然现在已经消失了,但确实很有帮助)。

viewController.xhtml

<h:body>
    <h:panelGroup layout="block" id="transactionControl">

                    <h:form>
                <h4>

                    <p:commandLink id="mfa" ajax="true" process="@form" update="content transactionBannerContent" styleClass="menuLink" oncomplete="showTransaction01Screens();">
                        <h:outputText value="MFA"></h:outputText>
                        <f:setPropertyActionListener target="#{viewController.destinationPage}" value="MFA01"/>
                    </p:commandLink>

                </h4>

                <h4>
                    <p:commandLink id="inq" ajax="true" process="@form" update="content transactionBannerContent" styleClass="menuLink" oncomplete="showTransaction01Screens();">
                        <h:outputText value="INQ"></h:outputText>
                        <f:setPropertyActionListener target="#{viewController.destinationPage}" value="INQ01"/>                            
                    </p:commandLink>


                </h4>

            </h:form>



    </h:panelGroup>

    <h:panelGroup layout="block" id="content" style="border-style: solid;">

        <ui:include src="#{viewController.destinationPage}.xhtml"></ui:include>

    </h:panelGroup>

</h:body>

mfa01.xhtml

<h:panelGroup layout="block" id="mfa01">

            <h:form id="mfa01Form">

                <p>
                    <span>
                        <h:outputLabel value="UCN" for="ucn"/>
                        <h:inputText id="ucn" value="#{mfa01BackingBean.mfa01FormVO.ucn}" size="20"/>
                    </span>
                </p>


                <p class="submitButton">
                    <p:commandButton id="submitButton" value="Go" ajax="true" actionListener="#{mfa01BackingBean.doMFA01}" process="@form"
                                     update="content transactionBannerContent" oncomplete="ajaxFinished('MFA01')">
                    </p:commandButton>
                </p>

            </h:form>

        </h:panelGroup>

mfa02.xhtml >

<h:panelGroup layout="block" id="mfa02">


            <h:form id="mfa02Form" prependId="true">

                <p>
                    <span style="width:25%">
                        <h:outputLabel value="Vessel Name"/>
                        <h:outputText id="vesselName"
                                     value="#{mfa02BackingBean.mfa02FormVO.vesselName}"/>
                    </span>


                    <span style="width:75%">
                        <h:outputLabel value="ETA"/>
                        <h:outputText id="eta"
                                     value="#{mfa02BackingBean.mfa02FormVO.eta}"/>
                    </span>

                </p>




                <p>
                    <span>
                        <h:outputLabel value="Unit ID" for="unitID"/>
                        <h:inputText id="unitID"
                                     value="#{mfa02BackingBean.mfa02FormVO.unitID}"
                                     size="20"
                                     required="true" validator="#{mfa02BackingBean.validateData}"/>
                    </span>
                </p>


                <p class="submitButton">
                    <p:commandButton id="submitButton" value="Go" ajax="true" action="#{mfa02BackingBean.doMFA02}"
                                     process="@form" update="content transactionBannerContent" oncomplete="ajaxFinished('MFA02')">
                        <f:param name="randomString" value="AAA"/>
                                     </p:commandButton>
                </p>


            </h:form>
        </h:panelGroup>

ViewController.java

package com.mcpplc.supportclient.webapp.managedBeans;


import javax.faces.bean.*;
import java.io.Serializable;

@ManagedBean (name = "viewController")
@SessionScoped
public class ViewController implements Serializable
{
    String destinationPage = "splash";
    String transactionID;


    public String getDestinationPage()
    {
        return destinationPage;
    }

    public void setDestinationPage( String destinationPage )
    {
        this.destinationPage = destinationPage;
        transactionID = destinationPage.toUpperCase();
    }

    public String getTransactionID()
    {
        return transactionID;
    }

    public void setTransactionID( String transactionID )
    {
        this.transactionID = transactionID;
    }
}

mfa01BackingBean.java

package com.mcpplc.supportclient.webapp.managedBeans;

import com.mcpplc.supportclient.webapp.Utils.JSFUtils;
import com.mcpplc.supportclient.webapp.valueObjects.*;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class Mfa01BackingBean
{
    @ManagedProperty(value = "#{viewController}")
    private ViewController viewController;

    private ImportConsignmentVO importConsignmentVO;
    private VoyageVO voyageVO;

    private Mfa01FormVO mfa01FormVO;

    private Mfa02FormVO mfa02FormVO;

    @PostConstruct
    public void init()
    {
        mfa01FormVO = new Mfa01FormVO();
    }

    public void doMFA01()
    {
        //pretend to get VOs
        importConsignmentVO = new ImportConsignmentVO();
        voyageVO = new VoyageVO();

        //set some VO stuff
        if ( mfa01FormVO.getUcn().equalsIgnoreCase( "123" ) )
        {
            importConsignmentVO.setUnitID("AJF1");
            voyageVO.setVesselName("Ever Glade");
        }
        else {
            importConsignmentVO.setUnitID("ZZZ1");
            voyageVO.setVesselName("Ever Champion");
        }
        importConsignmentVO.setType("41G1");
        importConsignmentVO.setWeight("25000");
        voyageVO.setEta("01/01/2011");

        constructMFA02Form();

        viewController.setDestinationPage("mfa02");

    }

    private void constructMFA02Form()
    {
        mfa02FormVO = new Mfa02FormVO();
        mfa02FormVO.setUnitID(importConsignmentVO.getUnitID());
        mfa02FormVO.setType(importConsignmentVO.getType());
        mfa02FormVO.setWeight(importConsignmentVO.getWeight());
        mfa02FormVO.setMfaRef("12345");
        mfa02FormVO.setVesselName(voyageVO.getVesselName());
        mfa02FormVO.setEta(voyageVO.getEta());

        JSFUtils.addObjectToRequest(Mfa02FormVO.class.getName(), mfa02FormVO);
    }

  .....getters&setters

}

mfa02BackingBean.java

package com.mcpplc.supportclient.webapp.managedBeans;

import com.mcpplc.supportclient.webapp.Utils.JSFUtils;
import com.mcpplc.supportclient.webapp.valueObjects.*;

import java.io.Serializable;
import java.util.*;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;

@ManagedBean
@ViewScoped
public class Mfa02BackingBean implements Serializable
{
    @ManagedProperty(value = "#{viewController}")
    private ViewController viewController;


    private Mfa02FormVO mfa02FormVO;    

    @PostConstruct
    public void init()
    {
       mfa02FormVO = (Mfa02FormVO) JSFUtils.getObjectFromRequest(Mfa02FormVO.class.getName());

    }

    public String doMFA02()
    {
        viewController.setDestinationPage("mfa01");
        return "viewController";
    }


     public void validateData ( FacesContext facesContext, UIComponent uiComponentToValidate, Object value)
    {
        String message = "";
        String requestData = (String) value;
        if ( !requestData.contains( "0" )  )
            {
                ((UIInput )uiComponentToValidate).setValid( false );
                message = "Incorrect format for Unit ID";
                facesContext.addMessage( uiComponentToValidate.getClientId(facesContext), new FacesMessage(message) );
                //JSFUtils.addObjectToRequest(Mfa02FormVO.class.getName(), mfa02FormVO);

            }



    }

.....getters&setters
}

Mfa01FormVO & Mfa02FormVO 只是带有 getter 和 getter 的值对象。 setters

我遇到的主要问题是在请求之间保存对象数据。当我从 mfa01 转到 mfa02 时,我会进行查找并填充一些 vo,然后将表单 vo 传递到 Flash 中。然后使用 vo 值构建 Mfa02 屏幕。我遇到的最大问题是 mfa02 上出现验证错误。最初,我将 bean 设置为 requestScoped,但是在验证失败后我丢失了 vo 对象。尽管我从 Flash 中获取该对象后立即将其添加回 Flash 中,但还是出现了这种情况。但奇怪的是,无法保证我什么时候会丢失该物体。如果我再次单击,有时我会立即丢失该对象,但有时它会再单击一次,然后我就会丢失它。

然后我将 mfa02backingbean 更改为 ViewScoped。然而,因为它完全是 ajax mfa02backingbean 没有在后续请求中重新初始化。这意味着我在第一次请求时设置的值将永远显示更多。我最终使用 ViewScoped 解决了这个问题,并将命令按钮更改为使用 Action 而不是 ActionListener,在该方法中我返回“viewController”字符串。我假设生命周期认为我正在返回一个新视图,因此它会清除视图范围中留下的任何内容。

我希望这段代码可以帮助其他正在寻找类似解决方案的人。

Decided to answer my own question as I have now have a full working ajax only prototype app. This fits my initial requirements of having each view saved as one .xhtml page and each view having it's own backing bean. Instead of further polluting my question here is the simplified code. (Thanks to BalusC for his previous answer that really helped although its now disappeared).

viewController.xhtml

<h:body>
    <h:panelGroup layout="block" id="transactionControl">

                    <h:form>
                <h4>

                    <p:commandLink id="mfa" ajax="true" process="@form" update="content transactionBannerContent" styleClass="menuLink" oncomplete="showTransaction01Screens();">
                        <h:outputText value="MFA"></h:outputText>
                        <f:setPropertyActionListener target="#{viewController.destinationPage}" value="MFA01"/>
                    </p:commandLink>

                </h4>

                <h4>
                    <p:commandLink id="inq" ajax="true" process="@form" update="content transactionBannerContent" styleClass="menuLink" oncomplete="showTransaction01Screens();">
                        <h:outputText value="INQ"></h:outputText>
                        <f:setPropertyActionListener target="#{viewController.destinationPage}" value="INQ01"/>                            
                    </p:commandLink>


                </h4>

            </h:form>



    </h:panelGroup>

    <h:panelGroup layout="block" id="content" style="border-style: solid;">

        <ui:include src="#{viewController.destinationPage}.xhtml"></ui:include>

    </h:panelGroup>

</h:body>

mfa01.xhtml

<h:panelGroup layout="block" id="mfa01">

            <h:form id="mfa01Form">

                <p>
                    <span>
                        <h:outputLabel value="UCN" for="ucn"/>
                        <h:inputText id="ucn" value="#{mfa01BackingBean.mfa01FormVO.ucn}" size="20"/>
                    </span>
                </p>


                <p class="submitButton">
                    <p:commandButton id="submitButton" value="Go" ajax="true" actionListener="#{mfa01BackingBean.doMFA01}" process="@form"
                                     update="content transactionBannerContent" oncomplete="ajaxFinished('MFA01')">
                    </p:commandButton>
                </p>

            </h:form>

        </h:panelGroup>

mfa02.xhtml

<h:panelGroup layout="block" id="mfa02">


            <h:form id="mfa02Form" prependId="true">

                <p>
                    <span style="width:25%">
                        <h:outputLabel value="Vessel Name"/>
                        <h:outputText id="vesselName"
                                     value="#{mfa02BackingBean.mfa02FormVO.vesselName}"/>
                    </span>


                    <span style="width:75%">
                        <h:outputLabel value="ETA"/>
                        <h:outputText id="eta"
                                     value="#{mfa02BackingBean.mfa02FormVO.eta}"/>
                    </span>

                </p>




                <p>
                    <span>
                        <h:outputLabel value="Unit ID" for="unitID"/>
                        <h:inputText id="unitID"
                                     value="#{mfa02BackingBean.mfa02FormVO.unitID}"
                                     size="20"
                                     required="true" validator="#{mfa02BackingBean.validateData}"/>
                    </span>
                </p>


                <p class="submitButton">
                    <p:commandButton id="submitButton" value="Go" ajax="true" action="#{mfa02BackingBean.doMFA02}"
                                     process="@form" update="content transactionBannerContent" oncomplete="ajaxFinished('MFA02')">
                        <f:param name="randomString" value="AAA"/>
                                     </p:commandButton>
                </p>


            </h:form>
        </h:panelGroup>

ViewController.java

package com.mcpplc.supportclient.webapp.managedBeans;


import javax.faces.bean.*;
import java.io.Serializable;

@ManagedBean (name = "viewController")
@SessionScoped
public class ViewController implements Serializable
{
    String destinationPage = "splash";
    String transactionID;


    public String getDestinationPage()
    {
        return destinationPage;
    }

    public void setDestinationPage( String destinationPage )
    {
        this.destinationPage = destinationPage;
        transactionID = destinationPage.toUpperCase();
    }

    public String getTransactionID()
    {
        return transactionID;
    }

    public void setTransactionID( String transactionID )
    {
        this.transactionID = transactionID;
    }
}

mfa01BackingBean.java

package com.mcpplc.supportclient.webapp.managedBeans;

import com.mcpplc.supportclient.webapp.Utils.JSFUtils;
import com.mcpplc.supportclient.webapp.valueObjects.*;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class Mfa01BackingBean
{
    @ManagedProperty(value = "#{viewController}")
    private ViewController viewController;

    private ImportConsignmentVO importConsignmentVO;
    private VoyageVO voyageVO;

    private Mfa01FormVO mfa01FormVO;

    private Mfa02FormVO mfa02FormVO;

    @PostConstruct
    public void init()
    {
        mfa01FormVO = new Mfa01FormVO();
    }

    public void doMFA01()
    {
        //pretend to get VOs
        importConsignmentVO = new ImportConsignmentVO();
        voyageVO = new VoyageVO();

        //set some VO stuff
        if ( mfa01FormVO.getUcn().equalsIgnoreCase( "123" ) )
        {
            importConsignmentVO.setUnitID("AJF1");
            voyageVO.setVesselName("Ever Glade");
        }
        else {
            importConsignmentVO.setUnitID("ZZZ1");
            voyageVO.setVesselName("Ever Champion");
        }
        importConsignmentVO.setType("41G1");
        importConsignmentVO.setWeight("25000");
        voyageVO.setEta("01/01/2011");

        constructMFA02Form();

        viewController.setDestinationPage("mfa02");

    }

    private void constructMFA02Form()
    {
        mfa02FormVO = new Mfa02FormVO();
        mfa02FormVO.setUnitID(importConsignmentVO.getUnitID());
        mfa02FormVO.setType(importConsignmentVO.getType());
        mfa02FormVO.setWeight(importConsignmentVO.getWeight());
        mfa02FormVO.setMfaRef("12345");
        mfa02FormVO.setVesselName(voyageVO.getVesselName());
        mfa02FormVO.setEta(voyageVO.getEta());

        JSFUtils.addObjectToRequest(Mfa02FormVO.class.getName(), mfa02FormVO);
    }

  .....getters&setters

}

mfa02BackingBean.java

package com.mcpplc.supportclient.webapp.managedBeans;

import com.mcpplc.supportclient.webapp.Utils.JSFUtils;
import com.mcpplc.supportclient.webapp.valueObjects.*;

import java.io.Serializable;
import java.util.*;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;

@ManagedBean
@ViewScoped
public class Mfa02BackingBean implements Serializable
{
    @ManagedProperty(value = "#{viewController}")
    private ViewController viewController;


    private Mfa02FormVO mfa02FormVO;    

    @PostConstruct
    public void init()
    {
       mfa02FormVO = (Mfa02FormVO) JSFUtils.getObjectFromRequest(Mfa02FormVO.class.getName());

    }

    public String doMFA02()
    {
        viewController.setDestinationPage("mfa01");
        return "viewController";
    }


     public void validateData ( FacesContext facesContext, UIComponent uiComponentToValidate, Object value)
    {
        String message = "";
        String requestData = (String) value;
        if ( !requestData.contains( "0" )  )
            {
                ((UIInput )uiComponentToValidate).setValid( false );
                message = "Incorrect format for Unit ID";
                facesContext.addMessage( uiComponentToValidate.getClientId(facesContext), new FacesMessage(message) );
                //JSFUtils.addObjectToRequest(Mfa02FormVO.class.getName(), mfa02FormVO);

            }



    }

.....getters&setters
}

Mfa01FormVO & Mfa02FormVO are just value objects with getters & setters

The main issue I encountered was saving object data between requests. When I go from mfa01 to mfa02 I do a lookup populate some vos and then pass a form vo into the Flash. Mfa02 screen is then constructed with the vo values. The big issue I had was when there was a validation error on mfa02. Initially I had the bean set to requestScoped however I lost the vo object after the validation failed. This was despite me adding the object back into the flash as soon as I got it from the Flash. The strange thing about this though was there was no guarantee when I would lose the object. If I clicked again sometimes I would lose the object straight away but sometimes it would remain for 1 more click and then i'd lose it.

I then changed mfa02backingbean to ViewScoped. However because it's completely ajax mfa02backingbean was not getting reinitialised on subsequent requests. This meant that whatever I set the values to on the first request would then be displayed forever more. I finally resolved this using ViewScoped and changing the Command Button to use an Action rather than ActionListener and in that method I return "viewController" String. I assume the lifecycle thinks I'm returning to a new view so it clears out anything left in the viewscope.

I hope this code helps anyone else looking for a similar solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文