无法使用RequestScoped bean填充Select元素?

时间:2018-01-21 19:00:56

标签: jsf initialization selectonemenu

我一直在努力完成一项看起来非常简单的任务,但不知何故我无法使用一些漂亮的hacky代码来解决它 - 我真的想避免这些。

问题本身已经简化为一个非常简单的任务:我有一个包含表单的单个页面的项目,我必须键入一个非空用户名并使用select元素(h:selectOneMenu)来选择一个此用户的“用户组”。这是提交给我的RequestScoped bean(这也是我在项目中唯一的bean)。只有验证规则(为了简化我的解释)是:“用户名”字段不能为空。

这是我的页面代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:p="http://xmlns.jcp.org/jsf/passthrough">

<h:head></h:head>
<h:body>
    <f:metadata>
        <f:event listener="#{userManagementBean.initializeGroupsList()}" type="preRenderView" />
    </f:metadata>


    <h:form>
        <h:inputText id="fieldUsername" value="#{userManagementBean.user.username}" p:placeholder="Username" required="true" />
        <h:message for="fieldUsername"/>

        <h:selectOneMenu id="fieldGroup" value="#{userManagementBean.usergroup_id}">
            <f:selectItem itemValue="#{null}" itemLabel="Please, select a group" />
            <f:selectItems value="#{userManagementBean.groupsList}" var="curGroup" itemLabel="#{curGroup.groupName}" itemValue="#{curGroup.id}" />
        </h:selectOneMenu>
        <h:message for="fieldGroup"/>

        <h:commandButton action="#{userManagementBean.submitValues()}" value="Submit data" />
    </h:form>
</h:body>
</html>

这是bean的代码,它初始化一个包含选择框元素的列表:

import java.io.Serializable;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

....

@RequestScoped
@Named
public class UserManagementBean implements Serializable {
    // PRIVATE FIELDS
    private User user = new User();
    private List<UserGroup> groupsList;
    private Integer usergroup_id;

    // BEAN'S PUBLIC METHODS
    public void initializeGroupsList() {
        groupsList = loadAllGroupsFromDatabase();
        System.out.print(String.format("%d groups have been loaded\n", groupsList.size()));
    }

    // Getters, setters and database-loading code has been ommited
    ...
}

问题是:何时/如何初始化用户组列表,用于填充页面上的select元素?

首先,我尝试使用&lt; f:event&gt;在“ preRenderView ”事件上调用 initializeGroupsList()的元素(如我上面编写的代码中所示)。所有内容都填充正常,但如果我选择一个用户组并且不输入任何用户名,则select元素会在提交表单后返回错误消息(“验证错误:值无效”),虽然它不应该给我任何验证错误,因为用户选择了有效的用户组。

其次,我尝试用&lt; f:viewAction&gt; 替换&lt; f:event&gt; ,后者调用 initializeGroupsList() 。当我第一次打开页面时,一切正常。但是当我提交没有用户名的表单时,页面会重新加载,显示验证错误,并且select元素根本没有填充任何用户组( initializeGroupsList()未被调用在这种情况下存在验证错误时。)

目前我正在通过删除&lt; f:event&gt; &lt; f:viewAction&gt; 元素以及annotationg initializeGroupsList来解决此问题 @PostConstruct 。问题是:如果我这样做,我将无法通过在 initializeGroupsList()中使用&lt; f:viewParam&gt; 来访问任何URL的查询字符串参数,这是我希望在不久的将来能够在这个页面中做的事情。

我应该如何调用 initializeGroupsList(),以避免在第一种和第二种情况下描述的这些错误,同时允许我访问 initializeGroupsList()中的URL查询字符串参数

提前致谢。

1 个答案:

答案 0 :(得分:0)

继续使用@PostConstruct初始化initializeGroupsList()。

关于视图参数你可以使用来自ominifaces的@Param(http://showcase.omnifaces.org/cdi/Param),它会为你注入它们,而不需要使用视图操作或查看事件。