У меня такое поведение, которого я не понимаю с помощью 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, а затем еще раз каждый раз, когда меняю значение.
Заранее спасибо