JSF 2.0 和 selectManyListbox 中的生命周期问题
Posted
技术标签:
【中文标题】JSF 2.0 和 selectManyListbox 中的生命周期问题【英文标题】:Trouble with lifecycle in JSF 2.0 and selectManyListbox 【发布时间】:2012-03-12 13:43:21 【问题描述】:我正在尝试制作一个简单的管理页面来管理用户列表。 jsf 代码如下所示:
<h:selectOneMenu id="selectUser" value="#adminBean.user_id" valueChangeListener="#adminBean.userSelected" >
<f:selectItems value="#adminBean.myModelUsersValues" />
<a4j:ajax event="valueChange" render="login password privilege_list" execute="@this"/>
</h:selectOneMenu >
<table>
<tr>
<td><h:outputLabel styleClass="LabelStyle" value="login: "/></td>
</tr>
<tr>
<td>
<h:inputText id="login" value="#adminBean.login"/>
</td>
<td>
<h:message for="login" style="color:red"/>
</td>
</tr>
<tr>
<td><h:outputLabel styleClass="LabelStyle" value="password: "/></td>
</tr>
<tr>
<td>
<h:inputText id="password" value="#adminBean.password"/>
</td>
<td>
<h:message for="password" style="color:red"/>
</td>
</tr>
<tr>
<td><h:outputLabel styleClass="LabelStyle" value="privilege list: "/></td>
</tr>
<tr>
<td>
<h:selectManyListbox id="privilege_list" value="#adminBean.privilegeList">
<f:selectItems value="#adminBean.privilegeValues" />
</h:selectManyListbox >
</td>
<td>
<h:message for="privilege_list" style="color:red"/>
</td>
</tr>
</table>
<br/>
<h:commandButton id="addButton" value="Add" action="#adminBean.addUser" styleClass="ButtonStyle"/>
<h:commandButton id="deleteButton" value="Delete" action="#adminBean.deleteUser" styleClass="ButtonStyle"/>
<h:commandButton id="clearButton" value="Clear" action="#adminBean.clear" styleClass="ButtonStyle"/>
问题是当页面加载时,所有项目都是空的。现在,当我单击“添加”按钮时,我发现 valueChangeListener="#adminBean.userSelected"
运行,它将我的权限列表替换为第一个用户的权限列表。当我使用清除按钮时也是如此 - 所有字段都是空的,但是当我再次单击添加按钮时,列表是来自第一个用户的列表(并且只有列表 - 没有其他输入文本)。我尝试将immediate="true"
添加到添加按钮并解决了这个问题,但是当然,我输入输入文本的所有值都不会传递给adminBean.addUser
操作方法。我的 bean 是 viewscoped(由于 selectManyListBox 上的验证错误,我需要使用它)。这是 Java 代码(到目前为止,addUser 方法只发送一个记录器方法并检查 i login 是否存在,以及是否在 priv.list 上选择了某事):
@ManagedBean(name="adminBean")
@ViewScoped
public class AdminBean
private String user_id ="";
private String login ="";
private String password ="";
private ArrayList<String> privilegeList = new ArrayList<String>();
private User model = new User();
private TreeMap<String, User> usersValuesBackendMap = new TreeMap<String, User>();
private TreeMap<String, String> privilegesValues = new TreeMap<String, String>();
private TreeMap<String, String> myModelUsersValues = new TreeMap<String, String>();
...
@javax.annotation.PostConstruct
public void init()
usersValuesBackendMap = queryDAO.getAllUsers();
for (Map.Entry<String, User> usr : usersValuesBackendMap.entrySet())
myModelUsersValues.put(usr.getValue().getLogin(), usr.getKey() );
privilegesValues = queryDAO.getFullPrivilegeList();
user_id = "";
public void userSelected(ValueChangeEvent event)
String newValue = event.getNewValue().toString();
User user = usersValuesBackendMap.get(newValue);
login = user.getLogin();
password = user.getPassword();
privilegesValues.clear();
for (String privilege: user.getPrivilegeValues() )
privilegesValues.put(privilege, privilege);
public String clear()
user_id ="";
login ="";
password ="";
privilegesValues = queryDAO.getFullPrivilegeList();
return "";
有趣的是,我在 clearing 方法中添加了 immediate="true" ,然后……相反的情况 - 列表没问题,但 inputTexts 已填满。
【问题讨论】:
【参考方案1】:一些事实:
valueChangeListener
在!oldValue.equals(newValue)
时运行。
valueChangeListener
不是客户端事件侦听器。它完全是服务器端。
valueChangeListener
完全独立于它是 ajax 请求还是普通请求。它在所有类型的请求上调用,包括正常的表单提交。
你需要<a4j:ajax listener>
。
<h:selectOneMenu id="selectUser" value="#adminBean.user_id">
<f:selectItems value="#adminBean.myModelUsersValues" />
<a4j:ajax event="valueChange" listener="#adminBean.userSelected" render="login password privilege_list" execute="@this"/>
</h:selectOneMenu >
与
public void userSelected(AjaxBehaviorEvent event)
User user = usersValuesBackendMap.get(user_id);
// ...
【讨论】:
希望我仍然可以依靠一些帮助,因为它是同一个项目。你的建议有效,但我还有另一个问题。当我添加用户时,一切正常,我可以在 SelectOneMenu 中看到新用户。但是,当我删除它时,它仍然在列表中(尽管选择时没有填写任何字段)。当然,我更新 bean 方法中的列表与添加用户操作中的列表完全相同。可能是什么问题?我尝试将按钮切换到 a4j:ajax,但它是相同的(不发送消息)。以上是关于JSF 2.0 和 selectManyListbox 中的生命周期问题的主要内容,如果未能解决你的问题,请参考以下文章
在同一个 Tomcat 服务器上部署 JSF 1.2 和 JSF 2.0 应用程序
RichFaces 3.3.3 和 JSF 2.0 工作示例