Проблема с жизненным циклом в 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 ответ

Решение

Некоторые факты:

  1. valueChangeListener работает когда !oldValue.equals(newValue),
  2. valueChangeListener не является прослушивателем событий на стороне клиента. Это полностью серверная сторона.
  3. 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);
    // ...
}
Другие вопросы по тегам