如何在保存时循环获取XPage中Repeat控件所有组件的值
解决Repeat控件输入值批量获取与保存的问题
这个问题我之前也碰到过——实时onChange提交确实容易因为异步刷新的冲突导致值丢失,尤其是用户快速输入的时候。换成保存按钮批量处理是个更稳妥的方案,具体实现步骤如下:
1. 给Repeat中的输入框设置唯一ID
首先,修改你Repeat里的xp:inputText组件,结合Repeat的indexVar(也就是你的i)给每个输入框生成唯一ID,这样后续循环时能精准定位到每一行的输入框:
<xp:repeat id="repeat1" rows="100" indexVar="i" value="#{javascript:viewScope.v1}"> <!-- 其他行内容 --> <xp:inputText value="#{viewScope.v3[i]}" id="qty_#{i}" style="width:80px"></xp:inputText> <!-- 其他行内容 --> </xp:repeat>
这里把ID改成qty_#{i},这样第一行的输入框ID是qty_0,第二行是qty_1,以此类推,保证每个输入框的ID唯一。
2. 编写保存按钮的批量处理逻辑
在保存按钮的SSJS代码中,我们循环遍历Repeat的所有行,通过唯一ID获取对应输入框的值,存入新的Vector后写入文档:
<xp:button value="保存" id="saveBtn"> <xp:eventHandler event="onclick" submit="true" refreshMode="complete"> <xp:this.action><![CDATA[#{javascript: // 获取Repeat的总行数(基于viewScope.v1的长度) var totalRows = viewScope.v1.size(); var updatedQtyVector = new java.util.Vector(); // 遍历每一行 for(var i = 0; i < totalRows; i++){ // 通过唯一ID获取当前行的输入框组件 var qtyInput = getComponent("qty_" + i); if(qtyInput){ // 获取输入框的值,这里可以根据需求做类型转换(比如转成数字) var qtyValue = qtyInput.getValue(); // 可选:值校验,比如确保是数字 if(qtyValue && !isNaN(qtyValue)){ qtyValue = parseInt(qtyValue, 10); } else { qtyValue = 0; // 空值或非数字时设为0,根据你的业务调整 } updatedQtyVector.addElement(qtyValue); } else { // 如果组件未找到(比如rows限制未渲染该行),添加默认值 updatedQtyVector.addElement(0); } } // 将新的Vector写入文档(假设你的文档数据源是document1,字段名为qtyList) var targetDoc = document1.getDocument(); targetDoc.replaceItemValue("qtyList", updatedQtyVector); targetDoc.save(); // 更新viewScope.v3,让页面后续显示最新的保存值 viewScope.v3 = updatedQtyVector; // 给用户提示保存成功 facesContext.addMessage(null, new javax.faces.application.FacesMessage("保存成功!")); }]]></xp:this.action> </xp:eventHandler> </xp:button>
关键细节说明
- 唯一ID的重要性:因为Repeat会渲染多个相同的输入框,只有给每个输入框设置唯一ID,才能通过
getComponent()精准获取到对应行的值。 - 避免异步冲突:批量处理把所有值的更新放在一次提交中,彻底解决了快速输入时多次异步提交导致的状态冲突问题。
- 值的类型处理:如果你的数量是数字类型,一定要做类型转换,避免把字符串存入文档字段。
- 行数兼容性:如果你的
viewScope.v1行数可能超过100,建议把Repeat的rows属性设为0(显示所有行),否则未渲染的行无法通过getComponent()获取到值。
内容的提问来源于stack exchange,提问作者Thomas Adrian
相关产品推荐
相关产品推荐

