Проблема с жизненным циклом в JSF 2.0 и выберите ManListbox - PullRequest
1 голос
/ 12 марта 2012

Я пытаюсь сделать простую страницу администратора для управления списком пользователей. Код 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 голос
/ 12 марта 2012

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

  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);
    // ...
}
...