JSF无法通过f:selectItems填充

时间:2013-09-08 02:58:27

标签: jsf jsf-2 selectonemenu

我正在尝试学习JSF 2,我已经按照本教程从java类方法加载f:selecItems返回ArrayList。我尝试使用

填充它
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,我已经尝试了但是它仍然没有加载。

我希望有人可以指出我做错了什么..

由于

1 个答案:

答案 0 :(得分:2)

您没有以正确的方式使用JSF表达式。 #{locationAndActivities.locations()}将告诉JSF寻找一个名为locations()的方法,你在bean中没有。使用括号时,您需要使用方法getLocations()的全名。如果删除了括号,JSF将查找该表达式的getter或setter。 例如 locationAndActivities.location会在需要返回对象时查找getLocation()方法,如果需要设置对象,则查找setLocation(Location location)

所以而不是:

locationAndActivities.locations()

使用:

locationAndActivities.locations

locationAndActivities.getLocations()

此外,始终避免在bean getter和setter中执行进程。最佳实践是在构造它之后立即填充bean中的arraylist(@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结构,您需要在将选定的Location对象传递给bean时使用转换器。转换器对于非String类型的数据类型是必需的,或者不是JSF具有内置转换器的那些类型(例如int,Integer,Long,long,Double,double等)。否则,您需要使用转换器将对象传递回bean。

另见:

SelectItem Wiki page