【问题标题】:PrimeFaces Ajax listener in SelectOneMenu tag is not working with viewParamSelectOneMenu 标记中的 PrimeFaces Ajax 侦听器不适用于 viewParam
【发布时间】:2014-09-10 04:13:28
【问题描述】:

我尝试使用 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() 方法,那么示例工作完美,但我需要页面参数。

请您帮忙解决。

【问题讨论】:

  • 您使用的是哪个 JSF 版本?
  • 我在 Glassfish 4.0 和 Netbeans 8.0 上使用 Primefaces 4.0 和 JSF 2.2.6。
  • @RobinsonRK - 我并不完全相信新的javax.faces.view.ViewScoped,而且我自己也有一些奇怪的行为。您仍然可以从@PostConstruct 中拉出请求参数
  • 我的答案是否停止工作

标签: ajax jsf primefaces selectonemenu viewparams


【解决方案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")); 


}

【讨论】:

    【解决方案2】:

    我和你有同样的问题。

    替换标签

    <f:viewParam name="id" value="#{dropdownViewBean.id}" required="true" />
    

    <f:viewParam name="id" value="#{dropdownViewBean.id}"/>
    

    很遗憾,我没有关于这个 Bug 的解释

    【讨论】:

    • 您好,这是一个老问题,但仍然是一个常见问题。我发现它是因为 Ajax 提交并且不发送参数。当页面没有收到所需的参数时,它会引发错误。您的回答是正确的,但我更喜欢使用 OmniFaces 组件来验证参数。
    猜你喜欢
    • 2011-11-03
    • 2014-01-28
    • 2014-11-13
    • 2012-04-22
    • 1970-01-01
    • 2015-01-09
    • 2013-09-16
    • 2021-04-24
    • 1970-01-01
    相关资源
    最近更新 更多