2013-09-08 2 views
1

Я пытаюсь изучить JSF 2, я следил за этим руководством, которое загружает f: selecItems из метода класса java, которые возвращают ArrayList. Я попытался заполнить его, используяJSF не может заполняться через f: selectItems

f:selectItem itemValue="Row 1" 

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

модель:

@ManagedBean 
@SessionScoped 
public class LocationsAndActivities implements Serializable 
{ 
    private final Location aLocations = new Location(); 
    private Activies aActivities = null; 
    private String selectedLocation = "--- SELECT LOCATION ---"; 
    private String selectedActivity = "--- CHOOSE ACTIVITY ---"; 
    private boolean hasActivities = Boolean.FALSE; 

    public ArrayList<SelectItem> getLocations() 
    { 
     return doGetLocations(); 
    } 
    private ArrayList<SelectItem> doGetLocations() 
    { 
     final ArrayList<SelectItem> modifiedLoc = aLocations.getLocations(); 
     modifiedLoc.add(0, new SelectItem("--- SELECT LOCATION ---")); 
     return modifiedLoc; 
    } 

    public void setLocation(final String location) 
    { 
     doSetLocation(location); 
    } 
    private void doSetLocation(final String location) 
    { 
     this.selectedLocation = location; 
     aActivities = new Activies(selectedLocation); 
     hasActivities = aActivities.hasActivityLists(); 
    } 

    public String getLocation() 
    { 
     return doGetLocation(); 
    } 
    private String doGetLocation() 
    { 
     return this.selectedLocation; 
    } 

    public ArrayList<SelectItem> getActivities() 
    { 
     return doGetActivities(); 
    } 
    private ArrayList<SelectItem> doGetActivities() 
    { 
     final ArrayList<SelectItem> returnValue; 
     if(aActivities == null) 
     { 
      hasActivities = Boolean.FALSE; 
      returnValue = new ArrayList<>(); 
     } 
     else 
     { 
      returnValue = aActivities.getActivities(); 
     } 
     returnValue.add(0,new SelectItem("--- CHOOSE ACTIVITY ---")); 
     return returnValue; 
    } 

    public String getActivity() 
    { 
     return doGetActivity(); 
    } 
    private String doGetActivity() 
    { 
     return this.selectedActivity; 
    } 

    public void setActivity(final String activity) 
    { 
     doSetActivity(activity); 
    } 
    private void doSetActivity(final String activity) 
    { 
     this.selectedActivity = activity; 
    } 

    public boolean isValidLocation() 
    { 
     return checkLocationValidity(); 
    } 
    private boolean checkLocationValidity() 
    { 
     return hasActivities; 
    } 

    public String getMessage() 
    { 
     return doGetMessage(); 
    } 
    private String doGetMessage() 
    { 
     return (hasActivities 
       ? "Please select location first" 
         : "You select " + selectedLocation 
         +" and activity of " + selectedActivity); 
    } 
} 

вид:

<!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:f= "http://java.sun.com/jsf/core" 
     xmlns:h="http://java.sun.com/jsf/html"> 
<h:head> 
<title>Title</title> 
<link href="./css/styles.css" 
     rel="stylesheet" type="text/css"/> 
</h:head> 
<h:body> 

<h:form> 
    Select Location of Adventure: 
    <h:selectOneMenu value="#{locationAndActivities.location}"> 
     <f:selectItems value="#{locationAndActivities.locations()}"/> 
     <f:ajax render="activityId" /> 
    </h:selectOneMenu><br /> 
    Select Location of Activities: 
    <h:selectOneMenu id="activityId" 
        value="#{locationAndActivities.activity}" 
        disabled="#{locationAndActivities.validLocation}"> 
     <f:selectItems value="#{locationAndActivities.activities()}"/> 
     <f:ajax render="messageId"/> 
    </h:selectOneMenu><br /> 
    <h:outputText id="messageId" value="#{locationAndActivities.message}"/> 
</h:form> 
</h:body> 
</html> 

В одном из вопросов здесь о заполнении JSF выпадающий, я увидел, что один отвечает, что я должен поставить @PostConstruct, я попробовал, но все равно он не загружается.

Я надеюсь, что кто-то мог бы указать, что я сделал неправильно ..

Благодаря

ответ

2

Вы не используете JSF выражения в правильном пути. #{locationAndActivities.locations()} расскажет JSF о поиске метода под названием locations(), который у вас не содержит в bean-компоненте. При использовании круглых скобок вам необходимо использовать полное имя метода getLocations(). Если вы удалите круглые скобки, JSF будет искать геттер или сеттер этого выражения. например,locationAndActivities.location будет искать способ getLocation(), если требуется вернуть объект, или setLocation(Location location), если требуется установить объект.

Таким образом, вместо:

locationAndActivities.locations()

Использование:

locationAndActivities.locations

или

locationAndActivities.getLocations()

Кроме того, всегда избегать процес ses в бобах и сеттерах. Лучшая практика заключается в том, чтобы заполнить arraylist в bean-компоненте сразу после его создания (@PostConstruct).

public class LocationsAndActivities implements Serializable 
{ 
    private ArrayList<Location> locations; 
    private Location location; 

    @PostConstruct 
    private void init(){ 
      //fill locations arraylist with data 
    } 


    public ArrayList<Location> getLocations(){ 
      return locations; 
    } 

    public Location getLocation(){ 
      return location; 
    } 

    public void setLocation(Location location){ 
      this.location = location; 
    } 
} 

<h:selectOneMenu value="locationAndActivities.location"> 
    <f:selectItem itemLabel="---Select Location---" noSelectionOption="true"> 
    <f:selectItems value="locationAndActivities.locations" var="var" itemValue="var"> 
</h:selectOneMenu> 

Примечания: Благодаря HTML структуры, необходимо использовать преобразователь при передаче выбранных объектов Места для боба. Преобразователи необходимы для типов данных, которые не относятся к типам строк или не относятся к тем типам, для которых JSF имеет встроенный преобразователь (например, int, Integer, Long, long, Double, double ... и т. Д.). В противном случае вам необходимо использовать конвертер, чтобы передать объект обратно в bean-компонент.

Смотрите также:

SelectItem Wiki page

+0

Привет Фаридом спасибо за объяснение. В учебнике, который я читаю, нет конвертера, я не знал конвертера, пока не увидел ваш ответ. Я нашел еще один учебник, который показывает 3 способа заселения h: selectOneMenu.Я последую этому руководству, и я вернусь сюда, чтобы обновить его. Также я не знаю @PostConstruct, поэтому я хотел бы спросить, работает ли он даже после первой загрузки? В приведенном выше примере второе поле со списком зависит от того, какое место было выбрано, поэтому я должен заполнить второй поле со списком после первой загрузки. – Gail

+0

Метод postconstruct - это mehtod, который вызывается сначала сразу после разборки компонента, и да, это может быть вызван снова после первой загрузки. – fareed

+0

@Gali Вам не нужен конвертер для некоторых типов данных, таких как примитивные типы данных и String. Чтобы передать объекты из вида в bean, вам нужно использовать преобразователи. Однако грязным обходным путем является передача идентификатора объекта обратно в bean-компонент и извлечение объекта из его идентификатора. Но для этого требуется дополнительное кодирование каждый раз, когда вы передаете объект. Использование конвертера всегда рекомендуется – fareed

Смежные вопросы