XForms Refresh失效问题排查(XSLTForms 1.7)
XForms实例数据修改后UI不更新的问题解决
问题描述
在Javascript中修改XForms实例数据时,XML数据已确认生效,但UI始终无法更新。尝试过<xf:refresh>元素,也手动调用了JS的xmodel.refresh()、rebuild()等刷新方法,均无效果。可通过点击两次“JS”按钮或在控制台执行fleur("instance('person')")验证模型数据已修改,Chromium和Firefox浏览器均出现该问题。
相关代码示例:
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet href="xsltforms-1.7/xsltforms.xsl" type="text/xsl"?> <?xsltforms-options debug="no"?> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ht="http://www.w3.org/1999/xhtml" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:ev="http://www.w3.org/2001/xml-events" lang="en"> <head> <script type="text/javascript"> <![CDATA[ function js_xforms() { console.log("js_xforms called"); var xmodel=document.querySelector('#model'); var person=xmodel.getInstanceDocument(); var fname=person.querySelector('fname'); console.log(fname.textContent); fname.textContent='Fred'; fname.setAttribute("js", "value"); xmodel.rebuild(); xmodel.recalculate(); xmodel.revalidate(); xmodel.refresh(); } ]]> </script> <xf:model id="model"> <xf:instance id="person"> <person xmlns=""> <fname js="initial">Joe</fname> <lname>Bloggs</lname> <tel>1234-5678</tel> </person> </xf:instance> </xf:model> </head> <body> <xf:input ref="fname"/> <xf:input ref="lname"/> <xf:input ref="tel"/> <xf:trigger> <xf:label>JS</xf:label> <xf:action ev:event="DOMActivate"> <xf:load resource="javascript:js_xforms()"/> <xf:refresh model="model"/> </xf:action> </xf:trigger> </body> </html>
问题原因
直接操作实例文档的DOM节点(比如修改textContent或调用原生setAttribute)会绕过XSLTForms内部的状态追踪机制。XForms框架维护着自己的实例数据状态管理系统,原生DOM修改不会触发该系统的变化感知,因此后续的刷新操作无法同步更新UI。
解决方案
必须使用XSLTForms提供的官方API来修改实例数据,确保框架能追踪到数据变化。
修改JS函数
function js_xforms() { console.log("js_xforms called"); var xmodel = document.querySelector('#model'); // 获取XForms实例对象(而非直接操作DOM文档) var personInstance = xmodel.getInstance('person'); // 使用API修改节点值 personInstance.setValue('fname', 'Fred'); // 使用API修改节点属性 var fnameNode = personInstance.getNode('fname'); personInstance.setNodeAttribute(fnameNode, 'js', 'value'); // 可选:手动触发刷新(API修改后通常会自动触发,若有特殊情况可添加) xmodel.refresh(); }
优化JS调用方式
避免使用<xf:load>调用JS,改用XForms规范的<xf:script>元素:
<xf:trigger> <xf:label>JS</xf:label> <xf:action ev:event="DOMActivate"> <xf:script>js_xforms();</xf:script> <xf:refresh model="model"/> </xf:action> </xf:trigger>
使用官方API修改数据时,XSLTForms会自动同步内部状态,确保UI能正确感知到数据变化并更新。
内容的提问来源于stack exchange,提问作者monojohnny
相关产品推荐
相关产品推荐

