XPages中repeat内编辑绑定viewScope的循环变量时,组件外viewScope值不更新的解决方法
核心问题根因
- 无差别的beforePageLoad初始化逻辑没有加回发判断,每次onchange触发提交时,代码都会重新把Test数组重置为初始的三个值,用户输入的修改会被直接覆盖
- 原生JS数组在XPages的EL解析中没有配置对应的索引访问解析器,直接绑定repeat遍历的临时变量
row时,输入框的值修改只会作用在临时变量的副本上,不会写回原数组;同时EL绑定仅跟踪作用域键对应的对象引用,数组内部元素的修改不会触发框架的脏检查机制,后续组件拉取绑定时无法拿到最新值 - 直接把数组对象绑定到文本组件时,框架会默认输出数组对象的
toString()结果,无法匹配预期的展示效果
推荐的最佳实现步骤
- 替换原生JS数组为Java集合对象,同时给初始化逻辑加首次加载判断,避免回发时重置数据
替换后的beforePageLoad代码:
// 仅在作用域无对应键时初始化,回发时保留已有数据 if(!viewScope.containsKey("Test")){ viewScope.Test = new java.util.ArrayList(); viewScope.Test.add("Hello"); viewScope.Test.add("Go"); viewScope.Test.add("Hello1"); }
*说明:ArrayList是标准Java集合,EL绑定可以正常跟踪其内部元素的读写操作,不会出现修改后框架无感知的问题。
- 调整重复组件的输入框绑定路径,避免直接绑定遍历的临时变量
直接绑定临时变量row会存在绑定路径解析不稳定的问题,改成带明确索引的绑定:
<xp:repeat id="repeat1" rows="30" value="#{viewScope.Test}" var="row" indexVar="i"> <xp:inputText id="inputText1" value="#{viewScope.Test[i]}"> <xp:eventHandler event="onchange" submit="true" refreshMode="partial" refreshId="computedField1"> </xp:eventHandler> </xp:inputText> </xp:repeat>
- 调整计算字段的输出逻辑,匹配预期的展示效果
直接绑定整个数组时,组件会输出数组对象的原生字符串表示,需要明确编写拼接逻辑:
<xp:text escape="true" id="computedField1" value="#{javascript: viewScope.Test.join(' | ')}"> </xp:text>
可选的兜底适配方案
如果部分XPages版本仍存在同步异常,可以在输入框的onchange事件处理逻辑中,手动给viewScope的数组键重新赋值,强制框架触发脏标记更新:
// 在事件处理的服务端逻辑末尾追加,强制标记数组为已更新 viewScope.Test = viewScope.Test;
内容的提问来源于stack exchange,提问作者Tim Savigar
相关产品推荐
相关产品推荐

