我在实现两个SelectOneMenu控件时遇到问题,第二个控件中的数据取决于第一个中的选择。 primeFaces展示中的这个示例与我想要实现的几乎相同:http://www.primefaces.org/showcase-labs/ui/pprSelect.jsf
除了我必须从数据库中获取数据。
上面的示例在同一个项目中正常工作。我使用的是NetBeans 7.0和GlassFish 3.1以及PrimeFaces 3.0.M2,这是最新一次(2011年6月20日)。
附加了JSF页面和托管bean的源代码。
<?xml version='1.0' encoding='UTF-8' ?>
<!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:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head><title>Facelet Title</title></h:head>
<h:body>
<p:log />
<center>
<h:form>
<h:outputText value="State: "/>
<p:selectOneMenu id="selectState" value="#{stateCityBean.selectedStateArray}">
<f:selectItem itemLabel="Select Any" itemValue="Empty String"/>
<p:ajax update="selectCity" listener="#{stateCityBean.updateCityMap}"/>
<f:selectItems value="#{stateCityBean.stateMap}" />
</p:selectOneMenu>
<p></p>
<h:outputText value="City: "/>
<p:selectOneMenu id="selectCity" value="#{stateCityBean.selectedCityArray}">
<f:selectItem itemLabel="Select Any" itemValue="Empty String"/>
<f:selectItems value="#{stateCityBean.cityMap}"/>
</p:selectOneMenu>
</h:form>
</center>
</h:body>
StateCityBean.java
package com.xyz.mbeans;
import com.iwizability.priceinfo.dao.*;
import com.iwizability.priceinfo.pojo.*;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import javax.faces.event.ValueChangeEvent;
@ManagedBean
@SessionScoped
public class StateCityBean {
private String selectedStateArray;
private Map<String, State> StateMap;
private Map<String, City> CityMap;
private String selectedCityArray;
public StateCityBean() {
System.out.println("Inside.............. ");
StateMap = new LinkedHashMap<String, State>();
CityMap = new LinkedHashMap<String, City>();
}
public String getSelectedStateArray() {return selectedStateArray;}
public void setSelectedStateArray(String selectedStateArray) {this.selectedStateArray = selectedStateArray;}
public Map<String, State> getStateMap() {
StateDaoImpl stateObj = new StateDaoImpl();
StateMap = stateObj.getState();
return StateMap;
}
public void setStateMap(Map<String, State> stateArray) {this.StateMap = stateArray;}
public String getSelectedCityArray() {return selectedCityArray;}
public void setSelectedCityArray(String selectedCityArray) {this.selectedCityArray = selectedCityArray;}
public Map<String, City> getCityMap() {
CityDaoImpl cityObj = new CityDaoImpl();
int stateId = 0;
if (selectedStateArray != null && !selectedStateArray.equals("")) {
stateId = StateMap.get(selectedStateArray).getId();
}
CityMap = cityObj.getCity(stateId);
return CityMap;
}
public void setCityMap(Map<String, City> CityArray) {
this.CityMap = CityArray;
}
public void updateCityMap() {
CityDaoImpl cityObj = new CityDaoImpl();
int stateId = 0;
if (selectedStateArray != null && !selectedStateArray.equals("")) {
stateId = StateMap.get(selectedStateArray).getId();
this.CityMap = cityObj.getCity(stateId);
}
}
}
在调试时,我可以看到调用updateCityMap方法但是SelectedStateArray变量为null。即使强制更改绑定的CityMap变量的值也不会更新selectCity下拉列表。
正如您所猜测的那样,我是JSF的新手,但问题因为我正在使用标签库的开发版本而更加复杂......
答案 0 :(得分:2)
我为您在项目中描述的完全相同的情况创建了一个演示。我的页面上有州和城市<p:selectOneMenu/>
元素。您选择一个州,城市更新。如果选择了不同的州,则城市将被删除,因为该州可能不存在。
不同之处在于我使用<p:ajax event="change" update="cities, cs"/>
来更新元素,如果状态不同,则使用actionListener来更新城市。
<p:selectOneMenu id="states" value="#{dataBean.selectedState}"
valueChangeListener="#{dataBean.stateChangeListener(event)}"
style="width: 150px;">
<f:selectItem itemLabel="" itemValue=""/>
<f:selectItems value="#{dataBean.states}"/>
<p:ajax event="change" update="cities, cs"/>
</p:selectOneMenu>
<h:outputLabel value="City:" for="cities"/>
<p:selectOneMenu id="cities"
value="#{dataBean.selectedCity}"
style="width: 150px;">
<f:selectItem itemLabel="" itemValue=""/>
<f:selectItems value="#{dataBean.cities}"/>
<p:ajax event="change" update="cs" />
</p:selectOneMenu>
整个项目和演示代码可以在我的博客上找到。我看到这篇文章并决定发布我的项目。 [博客]:http://javaevangelist.blogspot.com/2012/07/primefaces-ajax-enabled.html
答案 1 :(得分:1)
Primefaces正在尝试不同的东西。我不知道为什么。首先,您必须知道这些版本不稳定。 当您使用firebug分析代码时,您将推动它。 让我们假设两个组合谁有国家和城市的ID 当您更改第一个组合城市更新正确但城市组合'id更改为cities_input时,他们添加_input前缀。当我分析primefaces源代码。如果通过添加_input或_panel访问更改ID,则会有类似遍历树的代码。所以如果你第二次改变组合。一切都很完美,除了你说更新城市,但没有组件有id城市因为它有新的id cities_input。所以你的ajax无法正常工作。但他们在3.0m4或发布后纠正了这个错误。
这就是问题所在。这个问题的另一个例子就是有人为此打开jira。 如果您使用带有spring security j_username的登录名,则j_password将更改为j_username_input j_password_input。所以这打破了标准,代码在第二个ajax请求中不起作用。 希望这会有所帮助..
注意狮心的话。页面中3.m4中更改的Primefaces名称空间使用此选项。 的xmlns:P = “http://primefaces.org/ui”
答案 2 :(得分:0)
我做了一个州 - &gt;城市在我的jsf项目中选择与你一样。我找到的唯一区别是:
p:ajax
有change
个活动:<p:ajax event="change" update="city" listener="#{contatoMB.filterCities}" />
。p:ajax
位于f:selectItems
之后,但这应该不是问题。f:selectItems
列表是List<javax.faces.model.SelectItem>
,而不是Map<String, City>
,您是否尝试使用SelectItem
代替地图?<h:form id="contact-form" prependId="false">
,再次,这应该不是问题。h:selectOneMenu
位于p:panel
内,部分PrimeFaces组件在其他组件内部或外部时以奇怪的方式运行。如果这些都不起作用,那么问题就是你正在使用的PrimeFaces版本。我的PrimeFaces版本是2.2.1。
答案 3 :(得分:0)
我使用PrimeFaces 3.0.M4和命名空间:
<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">
似乎工作正常。
答案 4 :(得分:0)
也许它是primefaces版本,但你的bean中的更新方法看起来很复杂。
为什么不从ajax事件中检索选择的对象?这样就不需要定义该变量了。
public void update(AjaxBehaviorEvent event)
{
Object selectOneMenuObject = ((UIOutput)event.getSource()).getValue();
//String selectedStateArray = (String)((UIOutput)event...
//update temporary collection of second SelectOneMenu
}
不知道这对你有帮助,但这就是我的做法。
答案 5 :(得分:0)
你应该添加
event="change"
到p:ajax