我尝试使用selectOneMenu ajax监听器,但在我的页面接收参数时它无法正常工作。
在我的测试中,我使用了PrimeFaces ShowCase页面中显示的相同示例,但我的页面也通过viewParam和viewAction接收参数。
第一次更改selectOneMenu时,会触发动作侦听器,然后它会停止工作。
我的页面:
<?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://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Facelet Title</title>
</h:head>
<f:metadata>
<f:viewParam name="id" value="#{dropdownViewBean.id}" required="true" />
<f:viewAction action="#{dropdownViewBean.init}" />
</f:metadata>
<h:body>
<h:form>
<p:growl id="msgs" showDetail="true" />
<p:panel header="Select a Location" style="margin-bottom:10px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:selectOneMenu id="country" value="#{dropdownViewBean.country}" style="width:150px">
<p:ajax listener="#{dropdownViewBean.onCountryChange}" update="city" />
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownViewBean.countries}" />
</p:selectOneMenu>
<p:outputLabel for="city" value="City: " />
<p:selectOneMenu id="city" value="#{dropdownViewBean.city}" style="width:150px">
<f:selectItem itemLabel="Select City" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownViewBean.cities}" />
</p:selectOneMenu>
</h:panelGrid>
<p:separator />
<p:commandButton value="Submit" update="msgs" actionListener="#{dropdownViewBean.displayLocation}" icon="ui-icon-check" />
</p:panel>
</h:form>
</h:body>
</html>
豆子:
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
@Named(value = "dropdownViewBean")
@ViewScoped
public class DropdownViewBean implements Serializable {
private Map<String, Map<String, String>> data = new HashMap<String, Map<String, String>>();
private String country;
private String city;
private Map<String, String> countries;
private Map<String, String> cities;
private int id;
public DropdownViewBean() {
}
public void init() {
System.out.println("init id=" + id); // message is correctly shown when page starts
countries = new HashMap<String, String>();
countries.put("USA", "USA");
countries.put("Germany", "Germany");
countries.put("Brazil", "Brazil");
Map<String, String> map = new HashMap<String, String>();
map.put("New York", "New York");
map.put("San Francisco", "San Francisco");
map.put("Denver", "Denver");
data.put("USA", map);
map = new HashMap<String, String>();
map.put("Berlin", "Berlin");
map.put("Munich", "Munich");
map.put("Frankfurt", "Frankfurt");
data.put("Germany", map);
map = new HashMap<String, String>();
map.put("Sao Paolo", "Sao Paolo");
map.put("Rio de Janerio", "Rio de Janerio");
map.put("Salvador", "Salvador");
data.put("Brazil", map);
}
public Map<String, Map<String, String>> getData() {
return data;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Map<String, String> getCountries() {
return countries;
}
public Map<String, String> getCities() {
return cities;
}
public void onCountryChange() {
System.out.println("change"); // message is shown only the first time the combo is changed
if (country != null && !country.equals("")) {
cities = data.get(country);
} else {
cities = new HashMap<String, String>();
}
}
public void displayLocation() {
FacesMessage msg;
if (city != null && country != null) {
msg = new FacesMessage("Selected", city + " of " + country);
} else {
msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid", "City is not selected.");
}
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
重要的:
如果我拿出了元数据,viewParam和viewAction标签并用@PostConstruct标记了init()方法,那么样本工作正常,但我需要页面参数。
我请求你的帮助解决它。
答案 0 :(得分:1)
我不相信javax.faces.view.ViewScoped
,我只是懒得提出问题。首先,您不必使用ViewScoped
类型;它被引入导致最终弃用javax.faces.bean.ViewScoped
。截至目前,它仍然非常有效,同样适用。
该注释的唯一限制是它不适用于CDI bean,它是唯一允许@Inject
注释的视图范围。您似乎并不需要它,因此您应该能够安全地删除它。
您仍然可以从@PostConstruct
旧学校中提取GET参数:
@PostConstruct
public void init(){
FacesContext ctxt = FacesContext.getCurrentInstance();
Map<String,String> requestParameters = ctxt.getExternalContext().getRequestParameterMap();
int id = Integer.parseInt(requestParameters.get("id"));
}
答案 1 :(得分:0)
我和你有同样的问题。
替换标签
<f:viewParam name="id" value="#{dropdownViewBean.id}" required="true" />
使用
<f:viewParam name="id" value="#{dropdownViewBean.id}"/>
不幸的是我没有关于这个Bug的解释