Primefaces datalist删除行显示异常:删中间行视觉删除最后一行问题咨询
问题原因
- 核心是JSF视图状态和后端模型数据不同步,加上迭代组件按索引匹配条目导致的状态复用错误:
- 你给删除、新增按钮加了
immediate="true"属性,会跳过组件的「更新模型值」阶段,后端列表数据修改后,前端视图的组件树状态没有同步更新,渲染时依然按旧的索引绑定输入框的值 - 嵌套的
ui:repeat和p:dataList都属于迭代组件,你没有给p:dataList配置稳定的rowKey,JSF默认按行索引匹配组件,删除中间行后索引错位,原来绑定在第二行的输入框状态就被挂载到了第三行,视觉上就像删了最后一行 - 新增时旧值复现也是同理,索引错位后旧的输入框状态被复用给了新增的行,所以会带出之前输入的值
- 只修改
p:dataList的ID无法解决问题,因为问题出在迭代内部的输入组件状态匹配逻辑,不在外层列表ID上
- 你给删除、新增按钮加了
修复方案
- 首先删除所有
p:commandButton上的immediate="true"属性,你的场景不需要跳过模型更新流程,该属性是导致状态不同步的核心诱因 - 给
p:dataList添加rowKey属性,绑定到output对象的唯一主键字段,例如:
如果<p:dataList id="calculatorOutputList" value="#{cP.cO}" var="output" type="definition" rowKey="#{output.id}">output类没有主键字段,就重写该类的equals()和hashCode()方法,基于业务字段判断两个对象是否相等,让JSF可以精准识别被删除的条目,不再按索引匹配 - 给迭代内的所有输入组件添加和当前行绑定的唯一ID后缀,避免组件ID重复导致状态复用错误,例如:
<p:inputText id="oB_#{status.index}_#{output.id}" value="#{output.b}"/> - 检查后端
removeCalculatorOutput方法逻辑,确认是直接操作cP.cO对应的原生列表,没有操作副本 - 如果仍有问题,在新增、删除的后端方法末尾添加以下代码,强制刷新视图状态:
FacesContext.getCurrentInstance().renderResponse();
内容的提问来源于stack exchange,提问作者Martin Hofman
相关产品推荐
相关产品推荐

