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

Primefaces:如何在setter带参数时更新p:inputText

解决方案:PrimeFaces 5.3中TreeTable结合HashMap实现动态评分输入

针对你遇到的问题,以下是几种可行的解决方案,适配PrimeFaces 5.3版本:


方案1:直接绑定HashMap索引(最优解)

无需额外编写get/set方法,直接利用EL对集合的索引访问特性,让inputText自动读写HashMap中的值:

JSF代码

<p:treeTable value="#{yourTreeData}" var="gradingCat">
    <!-- 其他列 -->
    <p:column headerText="评分">
        <p:inputText id="cat" value="#{registerCandidateGradeBean.detailedGrades[gradingCat.pkCertGradeCategoryId]}" />
    </p:column>
</p:treeTable>

Bean代码

只需暴露detailedGrades的getter,并建议初始化时预先填充所有类别ID(避免用户输入时key不存在):

private HashMap<Integer, Double> detailedGrades = new HashMap<>();

@PostConstruct
public void init() {
    // 从数据库获取当前用户对应的所有类别列表
    List<CertGradeCategory> allCategories = yourService.getCategoriesForUser();
    // 预先将所有类别ID放入Map,避免输入时key缺失
    for (CertGradeCategory cat : allCategories) {
        detailedGrades.putIfAbsent(cat.getPkCertGradeCategoryId(), null);
    }
}

public HashMap<Integer, Double> getDetailedGrades() {
    return detailedGrades;
}

// 无需setter,HashMap是引用类型,EL会直接修改其内部数据

这种方式最简洁,EL会自动处理值的读取和写入,完全规避方法绑定的语法问题。


方案2:使用Ajax传递参数更新评分

如果因业务限制无法直接暴露HashMap,可通过Ajax传递类别ID和输入值来更新:

方式2.1:利用EL隐式对象传递参数

<p:inputText id="cat" value="#{registerCandidateGradeBean.getGradeForCat(gradingCat.pkCertGradeCategoryId)}">
    <p:ajax listener="#{registerCandidateGradeBean.updateGrade(gradingCat.pkCertGradeCategoryId, component.value)}" 
            process="@this" 
            event="change" />
</p:inputText>

Bean代码

public void updateGrade(int catId, Double newValue) {
    detailedGrades.put(catId, newValue);
}

方式2.2:通过请求参数获取值

<p:inputText id="cat" value="#{registerCandidateGradeBean.getGradeForCat(gradingCat.pkCertGradeCategoryId)}">
    <p:ajax listener="#{registerCandidateGradeBean.updateGrade}" process="@this">
        <f:param name="catId" value="#{gradingCat.pkCertGradeCategoryId}" />
    </p:ajax>
</p:inputText>

Bean代码

public void updateGrade(AjaxBehaviorEvent event) {
    FacesContext context = FacesContext.getCurrentInstance();
    // 获取类别ID
    int catId = Integer.parseInt(context.getExternalContext().getRequestParameterMap().get("catId"));
    // 获取输入框的新值(注意PrimeFaces 5.3中inputText的提交参数名带":input"后缀)
    String valueStr = context.getExternalContext().getRequestParameterMap().get(event.getComponent().getClientId() + ":input");
    Double newValue = valueStr != null && !valueStr.isEmpty() ? Double.parseDouble(valueStr) : null;
    
    detailedGrades.put(catId, newValue);
}

错误原因说明

  1. PropertyNotWritableException异常:你之前的Ajax listener写法错误,EL会将#{bean.setGradeForCat1(catId)}解析为属性访问而非方法调用,导致语法错误。
  2. valueChangeListener未触发:默认情况下,valueChangeListener仅在表单提交(或Ajax触发提交事件)时生效,且方法只能接受ValueChangeEvent类型参数,无法额外传递类别ID,因此该方式不适用于你的场景。

内容的提问来源于stack exchange,提问作者Myrto Pirli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 16:50:24