Проблема с жизненным циклом в JSF 2.0 и выберите ManListbox
Я пытаюсь сделать простую страницу администратора для управления списком пользователей. Код 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 только отправляет метод логгера и проверяет, существует ли мой логин, и был ли выбран sth в личном списке):
@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 "";
}
Интересно, что я добавил немедленный ="true" в метод очистки, а затем sth. происходит обратное - список в порядке, но 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);
// ...
}