托管bean的多个实例

时间:2015-03-05 14:03:51

标签: jsf jsf-2 primefaces

我使用素面选项卡显示多个输入表格。问题是,有时我需要实例化相同形式的2。它们当然都使用相同的Managed Bean,这导致第一个初始化表单的输入用相同的数据覆盖另一个。我需要能够在每个表单中放入不同的数据并集体提交它们。每个表单都会进入一个列表并转发进行计算。我一直在阅读范围范围范围,但唯一有效的范围是" Sessioned"。 Session只允许Managed Bean的一个实例,并将表单数据放入列表中," Request,View scope"不将数据分别放入列表中,也不保存数据。 Managed Bean是可序列化的并且在会话范围内。我已经阅读了另一篇文章但他们不能工作。有什么想法吗?

支持Bean

@ManagedBean
@SessionScoped

public class RequestCalculation {
    private CalculationRequest calcReq;
    private List<ViewTabs> formTabs;
    private String id;
    private boolean calcButton;

    public RequestCalculation() {
        calcReq = new CalculationRequest();
        formTabs = new ArrayList<ViewTabs>();
        calcButton = false;

    }

    public String loadForm(TcsBase loadForm) {

        id = loadForm.getId();

        ViewTabs tab = new ViewTabs();
        tab.setFormTitle("Form".concat(id));
        tab.setFormPage("Form".concat(id).concat(".xhtml"));
        formTabs.add(0, tab);
        calcReq.getFormCollection().add(0, loadForm);
        loadCalcButton();
        return "Main";
    }

    public void loadCalcButton() {
        if (formTabs.isEmpty())
            isCalcButton();
        else {
            calcButton = true;
        }
    }

    public void onTabClosed(TabCloseEvent e) {
        TabView tabView = (TabView) e.getComponent();
        int closingTabIndex = tabView.getChildren().indexOf(e.getTab());
        removeForm(closingTabIndex);
        formTabs.remove(closingTabIndex);
        loadCalcButton();
    }

    public void removeForm(int index) {
        TcsBase formIndex = calcReq.getFormCollection().get(index);
        String formId = formIndex.getId();

        // Creates a new instance of the selected form
        FacesContext fc = FacesContext.getCurrentInstance();
        fc.getELContext().getELResolver()
                .setValue(fc.getELContext(), null, "form".concat(formId), null);

        calcReq.getFormCollection().remove(index);
        formTabs.remove(index);
    }

    public String calculate() {
    CalculateService service = new CalculateService();
        CalculatorInterface calculateInterface = service.getCalculatePort();

        XStream xstream = new XStream(new StaxDriver());
        xstream.registerConverter(new JodaTimeConverter());

        // Here is where the client request (input) is converted to an Xml
        // string before going
        // to the Web Service

        String xml = xstream.toXML(calcReq);
        String request = calculateInterface.calculate(xml);

        // Here the response back from the Web Service is converted back from
        // Xml to a string
        // to be displayed to the user in Xhtml

        calcReq = (CalculationRequest) xstream.fromXML(request);

        FacesContext fc = FacesContext.getCurrentInstance();

        for (int i = 0; i < calcReq.getFormCollection().size(); i++) {

            TcsBase newFrm = calcReq.getFormCollection().get(i);
            String frmId = newFrm.getId();
            fc.getELContext()
                    .getELResolver()
                    .setValue(fc.getELContext(), null, "form".concat(frmId),
                            newFrm);
        }

        return null;

    }

    public List<ViewTabs> getFormTabs() {
        return formTabs;
    }

    public void setFormTabs(List<ViewTabs> formTabs) {
        this.formTabs = formTabs;
    }

    public boolean isCalcButton() {
        return calcButton;
    }

    public void setCalcButton(boolean calcButton) {
        this.calcButton = calcButton;
    }

}

** Html Menu **

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

<head>

</head>

<f:view>
    <h:body>

        <h:commandLink action="#{requestCalculation.loadForm(formA)}" value="FormA"  /> <br/>
        <h:commandLink action="#{requestCalculation.loadForm(formB)}" value="FormB" /> <br/><br/><br/>

    </h:body>
</f:view>
</html>

Html主页

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:c="http://java.sun.com/jsp/jstl/core">
<f:view>    

    <h:head>
        <title> TCS </title>

    </h:head>

    <h:form >


        <p:layout style="min-width:400px;min-height:700px " >
            <p:layoutUnit  position="north" style="text-align:center">
            <p style="text-align:center; font-size:28px">Tax Computation Service</p>
            </p:layoutUnit>

            <p:layoutUnit header="Menu" position="west" style="min-width:190px; min-height:50px; ">
                <p:panelMenu>
                    <p:submenu label="Forms">
                        <p:submenu label="Individual Forms">
                            <p:menuitem>
                                <ui:include src="Menu.xhtml" />
                            </p:menuitem>
                        </p:submenu>
                    </p:submenu>
                </p:panelMenu>
            </p:layoutUnit>

            <p:layoutUnit position="center" >
                <p:tabView  onTabShow="focus" widgetVar="tabView">
                    <p:ajax event="tabClose" listener="#{requestCalculation.onTabClosed}"/>
                    <c:forEach items="#{requestCalculation.formTabs}" var="listItem">
                        <p:tab  title="#{listItem.formTitle}"  closable="true" >
                            <ui:include src="#{listItem.formPage}" />
                         </p:tab>
                    </c:forEach>
                </p:tabView>

                    <p:panelGrid columns="0" >
                        <p:commandButton value="Calculate" action = "#{requestCalculation.calculate}"   ajax="false" rendered="#{requestCalculation.calcButton}" /> 
                    </p:panelGrid>
            </p:layoutUnit>

        </p:layout>

    </h:form>

</f:view>   
</html>

FormA Html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">

    <f:view>

        <h:head>
            <title> FormA</title>
        </h:head>

        <h:body>

            <p:focus />

            <p:panelGrid id="panelGridA" columns="2">
                <p:outputLabel value="Form ID: "  style="width: 725px" />
                <p:outputLabel value="#{formA.id}"  />        

                <p:outputLabel value="4.  . . "  style="width: 725px" />        
                <p:inputText id="input1" style="text-align:right" value="#{formA.line4}" converter="bdNullableConverter" onfocus="this.select()"/> 
                <p:outputLabel value="5. . . . . . . "  style="width: 725px" />        
                <p:inputText style="text-align:right" value="#{formA.line5}" converter="bdNullableConverter" onfocus="this.select()" /> 
                <p:outputLabel value="6.  . . . . . . . "  style="width: 725px" />        
                <p:outputLabel value="#{formA.line6}" converter="bdNullableConverter" /> 
            </p:panelGrid>
        </h:body>

    </f:view>
</html>

2 个答案:

答案 0 :(得分:1)

使用 ONE 托管bean,而不是尝试使用托管bean的多个实例,它可以通过以下方式访问类的多个实例。一个hashmap或arraylist或者你想要使用的任何东西。就像你在普通的旧java编程中一样。您不能有两个具有相同名称的变量:

@ViewScoped
@Named
public class RequestCalculations {

    Map<String, RequestCalculation> hm;

    @PostConstruct
    public init() {
        hm = new HashMap<>();
        // prepopulate if known upfront
        hm.put("1", new RequestCalculation());
        hm.put("2", new RequestCalculation());
    }

    public HashMap<String, RequestCalculation> getCalculations() {
        return hm;
    }
}

然后使用选项卡的tabIndex作为hashmap(或数组列表)的键。并在您的xhtml中执行类似

的操作
#{requestCalculations.calculations[myTabIndex]}

如果你需要这个包含(我认为你这样做),你可能需要通过include参数将其传递给include

答案 1 :(得分:0)

如果要使用manager bean的多个实例,则可以使用不同的名称在 faces-config.xml 文件中声明它并单独使用它。见例子

<managed-bean>
    <managed-bean-name>productSearchForm</managed-bean-name>
    <managed-bean-class>com.company.package.ProductSearchForm</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>productChildFilter</managed-bean-name>
    <managed-bean-class>com.company.package.ProductSearchForm</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

<managed-bean>
    <managed-bean-name>productAttachFilter</managed-bean-name>
    <managed-bean-class>com.company.package.ProductSearchForm</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>