重新创建 ViewScoped bean 而不是调用表单操作
ViewScoped bean recreated instead of calling form action
我有一个托管 bean,它是 ViewScoped。在这个 bean 中,我需要发送一个表单(使用 h:commandButton)。
这工作正常,除非我更改下拉菜单条目(触发事件并更新页面)。
更改下拉菜单的值后,提交表单重新创建 bean(并跳过与 h:commandButton 关联的操作)。
这是我的 XML:
<rich:panel styleClass="panel_grid_center fifty_percent"
header="Bid matrix">
<!-- display in case the user is not an admin -->
<h:panelGroup rendered="#{not loginBean.isAdmin}">
<h:outputText
value="You do not have sufficient permission to view this page." />
<br />
<h:form>
<h:commandLink action="index.xhtml"
value="Click here to go back to login page / search page." />
</h:form>
</h:panelGroup>
<!-- display if the user is an admin -->
<h:panelGroup rendered="#{loginBean.isAdmin}" id="bid_matrices_panel">
<h:panelGrid columns="2">
<!-- customer group panel -->
<rich:panel styleClass="contained_width fifty_percent"
header="Customer group">
<h:form>
<h:selectOneMenu
valueChangeListener="#{adminBean.onCustomerGroupChangeListener}"
value="#{adminBean.customerGroupService.displayCustomerGroup.spendMinimum}">
<f:selectItems
value="#{adminBean.customerGroupService.customerGroups}"
var="group" itemLabel="#{group.customerGroupLabel}"
itemValue="#{group.spendMinimum}" />
<a4j:ajax event="valueChange" execute="@this"
render="bid_matrices_panel" />
</h:selectOneMenu>
</h:form>
</rich:panel>
<!-- repeatables -->
<rich:panel styleClass="contained_width fifty_percent"
header="Repeatables">
</rich:panel>
</h:panelGrid>
<h:form>
<!-- we loop on each different commoditization (or however that's spelled) -->
<a4j:repeat var="bidmatrix_by_commoditization"
value="#{adminBean.bidMatrices}">
<rich:dataTable styleClass="contained_width"
value="#{bidmatrix_by_commoditization.bidMatricesByCoreStatus}"
var="matrix_by_core_status">
<!-- Display core status -->
<rich:column>
<f:facet name="header">
<h:outputText
value="#{bidmatrix_by_commoditization.commoditization}" />
</f:facet>
<h:outputText value="#{matrix_by_core_status.coreStatus}" />
</rich:column>
<!-- the percentages -->
<c:forEach var="index" begin="0"
end="#{adminBean.columnsNumber - 1}">
<rich:column>
<f:facet name="header">
<h:outputText value="#{adminBean.columnsHeaders[index]}" />
</f:facet>
<h:inputText
value="#{matrix_by_core_status.bidMatrices[index].percentage}">
<f:convertNumber type="percent" />
</h:inputText>
</rich:column>
</c:forEach>
</rich:dataTable>
</a4j:repeat>
<br />
<!-- update matrix button -->
<h:commandButton value="Update" action="#{adminBean.update}" />
</h:form>
</h:panelGroup>
</rich:panel>
我的豆子:
@ManagedBean(name = "adminBean")
@ViewScoped
public class AdminBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5917562235108703019L;
private CustomerGroupService customerGroupService;
private BidMatrixDao bidMatrixDao;
private List<BidMatricesByCommoditization> bidMatrices;
@PostConstruct
public void init() {
customerGroupService = new CustomerGroupService();
bidMatrixDao = new BidMatrixDaoImpl();
bidMatrices = bidMatrixDao.getBidMatricesByCustomerGroup(customerGroupService.getDisplayCustomerGroup());
}
public void onCustomerGroupChangeListener(ValueChangeEvent v) {
customerGroupService.setDisplayCustomerGroup((BigDecimal) v.getNewValue());
bidMatrices = bidMatrixDao.getBidMatricesByCustomerGroup(customerGroupService.getDisplayCustomerGroup());
}
public CustomerGroupService getCustomerGroupService() {
return customerGroupService;
}
/**
* @param customerGroupService
* the customerGroupService to set
*/
public void setCustomerGroupService(CustomerGroupService customerGroupService) {
this.customerGroupService = customerGroupService;
}
/**
* @return the bidMatrices
*/
public List<BidMatricesByCommoditization> getBidMatrices() {
return bidMatrices;
}
/**
* @param bidMatrices
* the bidMatrices to set
*/
public void setBidMatrices(List<BidMatricesByCommoditization> bidMatrices) {
this.bidMatrices = bidMatrices;
}
public int getColumnsNumber() {
return bidMatrices.get(0).getColumns();
}
public List<String> getColumnsHeaders() {
return bidMatrixDao.getAlignments();
}
public void update() {
bidMatrixDao.updateBidMatrices(bidMatrices);
}
}
请注意,我从 javax.faces.bean.ViewScoped;
正确导入了 ViewScoped
我还从我的 bean 中删除了 getters/setters,但它们在那里。
正如我所说,在不更改 h:selectOneMenu 值的情况下提交表单时工作正常。
谢谢!
编辑:我使用的是 jsf 2.2 (mojarra)、richfaces 4.1 和 wildfly 10.1
我通过移动 ajax 指令中使用的 id 解决了这个问题:
<a4j:ajax event="valueChange" execute="@this" render="bid_matrices_panel" />
我本来是把id放在parent panelGroup里面的,像这样:
<h:panelGroup rendered="#{loginBean.isAdmin}" id="bid_matrices_panel">
通过围绕我实际想要重新渲染的部分创建 rich:panel,我的问题得到解决:
<h:form>
<rich:panel id="bid_matrices_panel">
<! -- my data to render -->
</rich:panel>
<h:commandButton value="Update" action="#{adminBean.update}" />
</h:form>
我想重新呈现表单是问题的根源。
很确定我以前尝试过,但那时我也忘记了 implements Serializable
在我的 AdminBean 上...
我有一个托管 bean,它是 ViewScoped。在这个 bean 中,我需要发送一个表单(使用 h:commandButton)。 这工作正常,除非我更改下拉菜单条目(触发事件并更新页面)。 更改下拉菜单的值后,提交表单重新创建 bean(并跳过与 h:commandButton 关联的操作)。
这是我的 XML:
<rich:panel styleClass="panel_grid_center fifty_percent"
header="Bid matrix">
<!-- display in case the user is not an admin -->
<h:panelGroup rendered="#{not loginBean.isAdmin}">
<h:outputText
value="You do not have sufficient permission to view this page." />
<br />
<h:form>
<h:commandLink action="index.xhtml"
value="Click here to go back to login page / search page." />
</h:form>
</h:panelGroup>
<!-- display if the user is an admin -->
<h:panelGroup rendered="#{loginBean.isAdmin}" id="bid_matrices_panel">
<h:panelGrid columns="2">
<!-- customer group panel -->
<rich:panel styleClass="contained_width fifty_percent"
header="Customer group">
<h:form>
<h:selectOneMenu
valueChangeListener="#{adminBean.onCustomerGroupChangeListener}"
value="#{adminBean.customerGroupService.displayCustomerGroup.spendMinimum}">
<f:selectItems
value="#{adminBean.customerGroupService.customerGroups}"
var="group" itemLabel="#{group.customerGroupLabel}"
itemValue="#{group.spendMinimum}" />
<a4j:ajax event="valueChange" execute="@this"
render="bid_matrices_panel" />
</h:selectOneMenu>
</h:form>
</rich:panel>
<!-- repeatables -->
<rich:panel styleClass="contained_width fifty_percent"
header="Repeatables">
</rich:panel>
</h:panelGrid>
<h:form>
<!-- we loop on each different commoditization (or however that's spelled) -->
<a4j:repeat var="bidmatrix_by_commoditization"
value="#{adminBean.bidMatrices}">
<rich:dataTable styleClass="contained_width"
value="#{bidmatrix_by_commoditization.bidMatricesByCoreStatus}"
var="matrix_by_core_status">
<!-- Display core status -->
<rich:column>
<f:facet name="header">
<h:outputText
value="#{bidmatrix_by_commoditization.commoditization}" />
</f:facet>
<h:outputText value="#{matrix_by_core_status.coreStatus}" />
</rich:column>
<!-- the percentages -->
<c:forEach var="index" begin="0"
end="#{adminBean.columnsNumber - 1}">
<rich:column>
<f:facet name="header">
<h:outputText value="#{adminBean.columnsHeaders[index]}" />
</f:facet>
<h:inputText
value="#{matrix_by_core_status.bidMatrices[index].percentage}">
<f:convertNumber type="percent" />
</h:inputText>
</rich:column>
</c:forEach>
</rich:dataTable>
</a4j:repeat>
<br />
<!-- update matrix button -->
<h:commandButton value="Update" action="#{adminBean.update}" />
</h:form>
</h:panelGroup>
</rich:panel>
我的豆子:
@ManagedBean(name = "adminBean")
@ViewScoped
public class AdminBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 5917562235108703019L;
private CustomerGroupService customerGroupService;
private BidMatrixDao bidMatrixDao;
private List<BidMatricesByCommoditization> bidMatrices;
@PostConstruct
public void init() {
customerGroupService = new CustomerGroupService();
bidMatrixDao = new BidMatrixDaoImpl();
bidMatrices = bidMatrixDao.getBidMatricesByCustomerGroup(customerGroupService.getDisplayCustomerGroup());
}
public void onCustomerGroupChangeListener(ValueChangeEvent v) {
customerGroupService.setDisplayCustomerGroup((BigDecimal) v.getNewValue());
bidMatrices = bidMatrixDao.getBidMatricesByCustomerGroup(customerGroupService.getDisplayCustomerGroup());
}
public CustomerGroupService getCustomerGroupService() {
return customerGroupService;
}
/**
* @param customerGroupService
* the customerGroupService to set
*/
public void setCustomerGroupService(CustomerGroupService customerGroupService) {
this.customerGroupService = customerGroupService;
}
/**
* @return the bidMatrices
*/
public List<BidMatricesByCommoditization> getBidMatrices() {
return bidMatrices;
}
/**
* @param bidMatrices
* the bidMatrices to set
*/
public void setBidMatrices(List<BidMatricesByCommoditization> bidMatrices) {
this.bidMatrices = bidMatrices;
}
public int getColumnsNumber() {
return bidMatrices.get(0).getColumns();
}
public List<String> getColumnsHeaders() {
return bidMatrixDao.getAlignments();
}
public void update() {
bidMatrixDao.updateBidMatrices(bidMatrices);
}
}
请注意,我从 javax.faces.bean.ViewScoped;
正确导入了 ViewScoped
我还从我的 bean 中删除了 getters/setters,但它们在那里。
正如我所说,在不更改 h:selectOneMenu 值的情况下提交表单时工作正常。
谢谢!
编辑:我使用的是 jsf 2.2 (mojarra)、richfaces 4.1 和 wildfly 10.1
我通过移动 ajax 指令中使用的 id 解决了这个问题:
<a4j:ajax event="valueChange" execute="@this" render="bid_matrices_panel" />
我本来是把id放在parent panelGroup里面的,像这样:
<h:panelGroup rendered="#{loginBean.isAdmin}" id="bid_matrices_panel">
通过围绕我实际想要重新渲染的部分创建 rich:panel,我的问题得到解决:
<h:form>
<rich:panel id="bid_matrices_panel">
<! -- my data to render -->
</rich:panel>
<h:commandButton value="Update" action="#{adminBean.update}" />
</h:form>
我想重新呈现表单是问题的根源。
很确定我以前尝试过,但那时我也忘记了 implements Serializable
在我的 AdminBean 上...