1

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

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 的答案,我已经尝试过了,但它仍然没有加载。

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

谢谢

4

1 回答 1

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 之后立即在 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。

也可以看看:

选择项 Wiki 页面

于 2013-09-08T05:47:49.707 回答