You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:14:37