我使用素面选项卡显示多个输入表格。问题是,有时我需要实例化相同形式的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>
答案 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>