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); }
错误原因说明
- PropertyNotWritableException异常:你之前的Ajax listener写法错误,EL会将
#{bean.setGradeForCat1(catId)}解析为属性访问而非方法调用,导致语法错误。 - valueChangeListener未触发:默认情况下,valueChangeListener仅在表单提交(或Ajax触发提交事件)时生效,且方法只能接受
ValueChangeEvent类型参数,无法额外传递类别ID,因此该方式不适用于你的场景。
内容的提问来源于stack exchange,提问作者Myrto Pirli
相关产品推荐
相关产品推荐

