Жизненный цикл JSF - selectonemenu - PullRequest
0 голосов
/ 03 февраля 2012

У меня такое поведение, которого я не понимаю с помощью selectonemenu.Я попытаюсь объяснить это, задаваясь вопросом, знает ли кто-нибудь, что происходит.Я использую JSF2 со glassfish3.Мой код xhtml выглядит следующим образом:

<h:selectOneMenu  binding="#{cetBacking1.menuFamilies}"
                  valueChangeListener="#{cetBacking1.listenerFamilia}"
                  onchange="this.form.submit()">
   <f:selectItems value="#{cetBacking1.ompleFamiliesTemplate()}"></f:selectItems>
</h:selectOneMenu>
<h:commandButton value="Test" type="submit" action="#{cetBacking1.test()}">    </h:commandButton>

Я использую привязку, потому что в зависимости от значения selectOneMenu я буду отображать некоторые другие компоненты, но теперь это выходит за рамки.Командная кнопка предназначена для отправки.ompleFamiliesTemplate () возвращает список элементов выбора.И вспомогательный компонент:

@ManagedBean(name="cetBacking1")
@SessionScoped
public class cetBacking1 extends AbstractEntityAccessor implements Serializable {
private List<SelectItem> llistaFamilies = new ArrayList<SelectItem>();
private HtmlSelectOneMenu menuFamilies;
{
    System.out.println("cetBacking1.init");
    ompleFamiliesTemplate();
}


public void listenerFamilia(ValueChangeEvent event) {
    String novaFamilia = (String) event.getNewValue();
    System.out.println("cetBacking1.listenerFamilia: " + novaFamilia);
}

public List ompleFamiliesTemplate() {
    FacesContext context = FacesContext.getCurrentInstance();
    List<FamiliaTemplate> llistaFamiliestmp = new ArrayList<FamiliaTemplate>();
    System.out.println("cetBacking1.ompleFamiliesTemplate   !!!!!!");
    if (context.getExternalContext().getSessionMap().containsKey("LlistaFamilies")) {
        llistaFamiliestmp = (List<FamiliaTemplate>) context.getExternalContext().getSessionMap().get("LlistaFamilies");
        if (llistaFamilies.isEmpty()) {
            for (Iterator it = llistaFamiliestmp.iterator(); it.hasNext();) {
                FamiliaTemplate object = (FamiliaTemplate) it.next();
                llistaFamilies.add(new SelectItem(String.valueOf(object.getIdfamiliaTemplate()), object.getFamilia()));
            }
        }
    }
    return llistaFamilies;
}
public void submit() {
    System.out.println("cetBacking1.submit !!");
}

Я поместил некоторый файл System.out.println для отслеживания вызовов различных функций, конструктора компонента cetBacking1 и ompleFamiliesTemplate (), а также valueChangeListener.При первой загрузке страницы в журнале сервера появляются следующие сообщения:

INFO: cetBacking1.init
INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!
INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!

Вызывается функция бина {}, она вызывает cetBacking1.ompleFamiliesTemplate, а вторая cetBacking1.ompleFamiliesTemplate вызываетсяе: selectItems.Работает как положено.Теперь я изменяю значение selectOneMenu и в журнале появляется:

 INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!
 INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!
 INFO: cetBacking1.listenerFamilia: 2
 INFO: cetBacking1.listenerFamilia: 2
 INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!

Последний вызов cetBacking1.ompleFamiliesTemplate. Я думаю, что он вызывается f: selectItems.Но я не знаю, почему вызывается дважды в начале cetBacking1.ompleFamiliesTemplate, а затем дважды слушатель cetBacking1.listenerFamilia.Но следующий более удивителен для меня.Я снова меняю selectOneMenu и в журнале появляются: INFO: cetBacking1.ompleFamiliesTemplate !!!!!!ИНФОРМАЦИЯ: cetBacking1.ompleFamiliesTemplate !!!!!!ИНФОРМАЦИЯ: cetBacking1.listenerFamilia: 3 ИНФОРМАЦИЯ: cetBacking1.listenerFamilia: 3 ИНФОРМАЦИЯ: cetBacking1.listenerFamilia: 3 ИНФО: cetBacking1.ompleFamiliesTemplate !!!!!!

cetBacking1.ompleFamiliesTemplate вызывается дважды в начале, как и раньше, но слушатель вызывается три раза.Каждый раз, когда я меняю selectOneMenu, слушатель вызывается еще раз.Если я дважды изменю значение selectOneMenu, журнал будет выглядеть следующим образом:

 INFO: cetBacking1.ompleFamiliesTemplate   !!!!!! 
 INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!
 INFO: cetBacking1.listenerFamilia: 1
 INFO: cetBacking1.listenerFamilia: 1
 INFO: cetBacking1.listenerFamilia: 1
 INFO: cetBacking1.listenerFamilia: 1
 INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!
 INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!
 INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!
 INFO: cetBacking1.listenerFamilia: 2
 INFO: cetBacking1.listenerFamilia: 2 
 INFO: cetBacking1.listenerFamilia: 2
 INFO: cetBacking1.listenerFamilia: 2
 INFO: cetBacking1.listenerFamilia: 2
 INFO: cetBacking1.ompleFamiliesTemplate   !!!!!!

Вопрос в том, почему cetBacking1.ompleFamiliesTemplate вызывается дважды, когда я изменяю значение selectOneMenu, перед выполнением слушателя.И почему слушатель выполняется дважды, когда я в первый раз изменяю значение selectOneMenu, а затем еще раз каждый раз, когда меняю значение.

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 03 февраля 2012

В JSF геттеры могут вызываться несколько раз за один запрос.Вот хороший ответ на этот вопрос: Почему JSF вызывает геттер несколько раз

0 голосов
/ 26 марта 2012

Месяц назад у меня была такая же проблема. Решение состоит в том, что SessionScope и привязка несовместимы.

Вы должны удалить привязку на вашей jsf-странице, и все работает нормально. Для заполнения SelectCombo вы можете использовать List<SelectItem> с элементами.

...