SelectOneMenu标记中的PrimeFaces Ajax侦听器不能与viewParam一起使用

时间:2014-07-18 22:51:57

标签: ajax jsf primefaces selectonemenu viewparams

我尝试使用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()方法,那么样本工作正常,但我需要页面参数。

我请求你的帮助解决它。

2 个答案:

答案 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的解释