PrimeFaces selectOneMenu onChange事件失效问题求助
问题分析与解决方案
我看了你的代码,发现几个关键问题导致<p:ajax>的listener没触发,控制台没输出,也没法更新第二个下拉框。咱们一步步来修复:
1. 转换器的类型比较错误(最核心问题)
你的PacijentiConverter里,getAsObject方法用了value == p.getPacijent_id()来匹配ID,但value是字符串类型,而p.getPacijent_id()应该是数字类型(比如Integer),直接用==比较永远不会相等,导致转换器无法正确把选中的ID转换成Pacijenti对象。AJAX请求无法传递有效的实体,listener自然不会触发。
修复后的转换器代码:
@FacesConverter(forClass=Pacijenti.class) public class PacijentiConverter implements Converter { @Override public Object getAsObject(FacesContext fc, UIComponent uic, String value) { if(value != null && value.trim().length() > 0) { try { Integer pacijentId = Integer.parseInt(value); for(Pacijenti p : CommonServices.fetchPacijentiFromDB()) { // 用equals比较数字类型,避免字符串和数字的==匹配失败 if(pacijentId.equals(p.getPacijent_id())) { return p; } } throw new ConverterException(new FacesMessage("Pacijent s ID-om " + value + " nije pronađen")); } catch(NumberFormatException e) { throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Greška u konverziji", "Neispravan ID pacijenta")); } } else { return null; } } @Override public String getAsString(FacesContext context, UIComponent component, Object value) { if (value == null) { return ""; } if (value instanceof Pacijenti) { return String.valueOf(((Pacijenti) value).getPacijent_id()); } else { throw new ConverterException(new FacesMessage(value + " nije validan pacijent")); } } }
2. 第二个下拉框的disabled属性EL表达式错误
你写的disabled="#{empty selectedPacijent}"没有指定Bean前缀,EL表达式找不到这个变量,会导致组件状态异常,影响AJAX更新后的渲染。
修复后的代码:
<p:selectOneMenu id="bolestiList" value="#{termini.selectedBolest}" filter="true" filterMatchMode="contains" disabled="#{empty termini.selectedPacijent}"> <f:selectItem itemLabel="Odaberi bolest" itemValue="" noSelectionOption="true" /> <f:selectItems value="#{termini.bolesti_list}" var="bolest" itemLabel="#{bolest.naziv_bolesti}" itemValue="#{bolest}" /> </p:selectOneMenu>
3. 明确指定AJAX触发事件(可选,但更稳妥)
虽然PrimeFaces的<p:ajax>默认是change事件,但明确加上event="change"可以避免潜在的触发问题:
<p:ajax listener="#{termini.writeSomething}" update="bolestiList" event="change" />
4. 调试与功能扩展
修复上述问题后,你可以在writeSomething方法里添加逻辑,根据选中的患者加载对应的病史:
public void writeSomething() { System.out.println("AJAX listener pokrenut! Odabran pacijent: " + selectedPacijent); // 根据选中的患者加载对应的病史 if(selectedPacijent != null) { bolesti_list = CommonServices.fetchBolestiByPacijentId(selectedPacijent.getPacijent_id()); } else { bolesti_list = new ArrayList<>(); } }
内容的提问来源于stack exchange,提问作者JuliusCezarus
相关产品推荐
相关产品推荐

