Я хотел бы попросить некоторой помощи в понимании конкретного поведения, которое JSF показывает на этапе проверки
терпит неудачу.
Я использую:
- Tomcat 7.0.2
- JSF 1.2_12
- RichFaces 3.3.3
Описание проблемы.
Я написал форму с 4 полями ввода: inputText и 3 selectOneMenu. Требуется inputText
в то время как selectOneMenus не требует никакой проверки. Прикрепленный к первому selectOneMenu (строка 32),
является тегом a4j: support, так что всякий раз, когда происходит событие изменения, список элементов второго
и третий selectOneMenu (строки 44 и 58) заполнены правильно. В частности, после загрузки
В двух списках элементов метод вызывает значение второго и третьего selectOneMenu
к нулю. Этот механизм, кажется, работает нормально, пока я не отправлю форму без заполнения ввода
текст: как и ожидалось, проверка JSF не удалась, но когда я изменил значение первого selectOneMenu,
на странице отображаются значения, указанные до того, как проверка JSF не удалась в течение
третий selectOneMenu (обратите внимание, что actionListener по-прежнему вызывается и значения второго и
третье selectOneMenu по-прежнему обнуляется).
Поскольку я использую простой PhaseListener, я заметил следующее:
перед неудачей проверки JSF каждый раз, когда я изменяю значение первого selectOneMenu, JSF life
цикл всегда вызывает метод get для второго и третьего selectOneMenu во время рендеринга
Фаза ответа. Таким образом, JSF может «видеть», что эти значения были установлены в нуль во время
этап вызова приложения.
После сбоя проверки JSF перестает вызывать эти геттеры, когда я изменяю значение первого
selectOneMenu.
Вот мой взгляд
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<head>
<title>Prove Rich</title>
</head>
<body>
<h2>Prove Rich</h2>
<f:view>
<a4j:outputPanel ajaxRendered="true">
<h:messages style="color:red" />
</a4j:outputPanel>
<h:form>
<p>
Input required: <h:inputText value="#{provaProbReplyBean.inputRequired}" required="true" />
</p>
<p>
<h:outputText value="Scegli il canale:" />
<h:selectOneMenu value="#{provaProbReplyBean.canale}">
<f:selectItem itemLabel="--" itemValue="" />
<f:selectItem itemLabel="Profamily" itemValue="Profamily" />
<f:selectItem itemLabel="Captive" itemValue="Captive" />
<a4j:support event="onchange" action="#{provaProbReplyBean.caricaProcBanche}" ajaxSingle="true" reRender="procedure, banche" />
</h:selectOneMenu>
</p>
<p>
<h:outputText value="Scegli la procedura:" />
<h:selectOneMenu id="procedure" value="#{provaProbReplyBean.procedura}">
<f:selectItem itemLabel="--" itemValue="" />
<f:selectItems value="#{provaProbReplyBean.procedureList}" />
<!-- immediately save the current value -->
<a4j:support event="onchange" ajaxSingle="true" />
</h:selectOneMenu>
</p>
<p>
<h:outputText value="Scegli la banca:" />
<h:selectOneMenu id="banche" value="#{provaProbReplyBean.banca}">
<f:selectItem itemLabel="--" itemValue="" />
<f:selectItems value="#{provaProbReplyBean.bancheList}" />
<!-- immediately save the current value -->
<a4j:support event="onchange" ajaxSingle="true" />
</h:selectOneMenu>
</p>
<p><h:commandButton value="Submit" /></p>
</h:form>
</f:view>
</body>
</html>
А вот и моя модель:
public class ProvaProbReply {
private String inputRequired;
private String canale;
private String procedura;
private String banca;
private Map<String, List<SelectItem>> canaliProc = new HashMap<String, List<SelectItem>>();
private Map<String, List<SelectItem>> canaliBanche = new HashMap<String, List<SelectItem>>();
private List<SelectItem> procedureList = new ArrayList<SelectItem>();
private List<SelectItem> bancheList = new ArrayList<SelectItem>();
public ProvaProbReply() {
List<SelectItem> l = new ArrayList<SelectItem>();
l.add(new SelectItem("Cessione del quinto"));
l.add(new SelectItem("Credito al consumo"));
l.add(new SelectItem("Mutui"));
canaliProc.put("Profamily", l);
l = new ArrayList<SelectItem>();
l.add(new SelectItem("Credito al consumo"));
canaliProc.put("Captive", l);
l = new ArrayList<SelectItem>();
canaliBanche.put("Profamily", l);
l = new ArrayList<SelectItem>();
l.add(new SelectItem("BDL"));
l.add(new SelectItem("BM"));
l.add(new SelectItem("BPM"));
l.add(new SelectItem("CRA"));
canaliBanche.put("Captive", l);
}
public String getInputRequired() {
return inputRequired;
}
public void setInputRequired(String ir) {
inputRequired = ir;
}
public String getCanale() {
return canale;
}
public void setCanale(String c) {
canale = c;
}
public String getProcedura() {
System.out.println("\ngetProcedura called\n");
return procedura;
}
public void setProcedura(String p) {
procedura = p;
}
public String getBanca() {
System.out.println("\ngetBanca called\n");
return banca;
}
public void setBanca(String b) {
banca = b;
}
public List<SelectItem> getProcedureList() {
return procedureList;
}
public List<SelectItem> getBancheList() {
return bancheList;
}
public String caricaProcBanche() {
System.out.println("\nListener called\n");
procedureList.clear();
bancheList.clear();
if(canale != null && !canale.equals("")) {
procedureList.addAll(canaliProc.get(canale));
bancheList.addAll(canaliBanche.get(canale));
}
System.out.println("BEFORE setting:\n");
System.out.println("\nProcedura: "+procedura+"\n");
System.out.println("Banca: "+banca+"\n");
procedura = null;
banca = null;
System.out.println("\n\n\nAFTER setting:\n");
System.out.println("\nProcedura: "+procedura+"\n");
System.out.println("Banca: "+banca+"\n");
return "";
}
}