Проблема с Primefaces 3.0.M2 Поведение Ajax SelectOneMenu - PullRequest
21 голосов
/ 22 июня 2011

У меня проблема с реализацией двух элементов управления SelectOneMenu, где данные во втором зависят от выбора, сделанного в первом.Этот пример на витрине primeFaces почти такой же, как я хочу реализовать: http://www.primefaces.org/showcase-labs/ui/pprSelect.jsf

, за исключением того, что мне нужно получить данные из базы данных.

Приведенный выше пример работает правильнов том же проекте.Я использую NetBeans 7.0 с GlassFish 3.1 и PrimeFaces 3.0.M2, последней версией (20 июня 2011 г.).

Исходный код страницы JSF и управляемого компонента прилагается.

<?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, но проблема усугубляется тем, что я использую неподвижное вразрабатываемая версия библиотеки тегов ...

Ответы [ 6 ]

2 голосов
/ 06 июля 2012

Я создал демо для той же ситуации, которую вы описали в своем проекте.У меня есть элементы штата и города <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 голос
/ 12 января 2012

Primefaces пытается что-то другое.Я не знаю почему.Прежде всего вы должны знать, что эти релизы не стабильны.Когда вы анализируете код с помощью firebug, вы отправляете это.Предположим, два комбо имеют идентификаторы стран и городов, когда вы изменили первое комбо-обновление городов корректно, но комбо-код города поменяется на towns_input, они добавляют префикс _input.Когда я анализирую исходные коды.Есть коды что-то вроде дерева обхода, если посещенный идентификатор изменения, добавив _input или _panel.Так что если вы измените комбо во второй раз.Все работает отлично, за исключением того, что вы сказали, обновить города, но нет компонента, который имеет идентификаторы городов, потому что у него есть новый идентификатор towns_input.Таким образом, ваш AJAX не работает правильно.Но они исправляют эту ошибку в 3.0m4 или после релизов.

Это проблема.Еще один пример этой проблемы - ошибка, которую кто-то может открыть для этого.Если вы используете логин с пружинной защитой j_username, j_password смените на j_username_input j_password_input.Таким образом, это нарушает стандарт и код не работает во втором запросе ajax.Надеюсь, это поможет ..

обратите внимание на слова львиное сердце.Пространства имен Primefaces, измененные в 3.m4 на страницах, используют это.XMLNS: р = "http://primefaces.org/ui"

0 голосов
/ 06 июля 2012

Вы должны просто добавить

event="change"

к p: ajax

0 голосов
/ 13 февраля 2012

Возможно, это версия с простыми лицами, но ваш метод обновления в вашем bean-компоненте выглядит довольно сложным.

Почему бы не получить объект выбора из события ajax ?, таким образом вам не нужно определять эту переменную.

public void update(AjaxBehaviorEvent event)
{
    Object selectOneMenuObject = ((UIOutput)event.getSource()).getValue();

    //String selectedStateArray = (String)((UIOutput)event...
    //update temporary collection of second SelectOneMenu
}

Не знаю, поможет ли это вам, но так я и делаю.

0 голосов
/ 01 декабря 2011

Я использую 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">

Кажется, что работает нормально.

0 голосов
/ 01 сентября 2011

Я сделал штат -> выбор города в моем проекте JSF так же, как вы сделали.Единственные различия, которые я нашел:

  • my p:ajax имеет событие change: <p:ajax event="change" update="city" listener="#{contatoMB.filterCities}" />.
  • my p:ajax стоит последним после f:selectItems, но этоНе должно быть проблем.
  • Мой список f:selectItems в выбранном городе - List<javax.faces.model.SelectItem>, а не Map<String, City>. Вы пытались использовать SelectItem s вместо своей карты?
  • моя форма имеет идентификатор и prependId false <h:form id="contact-form" prependId="false">, опять же, это не должно быть проблемой.
  • my h:selectOneMenu находится внутри p:panel, некоторые компоненты PrimeFaces ведут себя странным образом, когдавнутри или снаружи некоторых других компонентов.

Если ничего из этого не работает, возможно, проблема в используемой вами версии PrimeFaces.Моя версия PrimeFaces - 2.2.1.

...