为什么在具有绑定属性的重复中插入新行时,重复索引不会更新到 orbeon xforms 中新插入的行?
How come that when inserting a new row in a repeat with a bind attribute the repeat index is not updated to the newly inserted row in orbeon xforms?
我们的软件生成 XForms。对于重复结构,它会生成 xf:repeat 个元素,该元素具有引用绑定模型的绑定属性以确定其重复集合。从 xforms 规范中我们了解到,重复索引应该始终更新到最后插入的行,但事实并非如此。当使用 ref 或 nodeset 属性进行重复时,重复索引会按预期更新。
演示这个的小例子:
<?xml version="1.0" encoding="UTF-8"?>
<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:idc="http://www.inventivedesigners.com/xbl"
xmlns:exf="http://www.exforms.org/exf/1-0"
xmlns:saxon="http://saxon.sf.net/">
<xhtml:head>
<xhtml:meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<xhtml:title>Test</xhtml:title>
<xf:model id="m-default">
<xf:instance id="i-default">
<data xmlns="">
<repeat>
<id>1</id>
</repeat>
</data>
</xf:instance>
<xf:instance id="i-counter">
<form xmlns="">
<counter>1</counter>
</form>
</xf:instance>
<!-- bindings -->
<xf:bind nodeset="repeat" id="repeat-bind" />
</xf:model>
</xhtml:head>
<xhtml:body style="width: 80%; margin-left: auto; margin-right: auto;">
<xhtml:table style="border: 1px solid black; margin-top: 50px;">
<xhtml:tbody>
<xf:repeat id="my_repeat" bind="repeat-bind">
<xhtml:tr>
<xhtml:td>
<xf:output ref="id" />
</xhtml:td>
</xhtml:tr>
</xf:repeat>
</xhtml:tbody>
</xhtml:table>
<xf:trigger>
<xf:label>Insert</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue value="number(.) + 1" ref="instance('i-counter')/counter"/>
<xf:insert position="after" nodeset="repeat" at="index('my_repeat')"/>
<xf:setvalue value="instance('i-counter')/counter" ref="repeat[last()]/id"/>
</xf:action>
</xf:trigger>
<fr:xforms-inspector/>
</xhtml:body>
</xhtml:html>
如果你按四次按钮,你会看到顺序是 1,4,3,2 而我们期望的是 1,2,3,4。在 repeat 上使用 ref 属性时,输出符合预期。
我用 Orbeon 4.4 和最新的 4.8 对此进行了测试,但行为是相同的。使用 bind 和 ref 有什么区别?
我更新了 github issue 并解释了它发生的原因。
作为解决方法,您可以使用 xf:setindex
在数据中插入新节点后显式设置重复索引。
我们的软件生成 XForms。对于重复结构,它会生成 xf:repeat 个元素,该元素具有引用绑定模型的绑定属性以确定其重复集合。从 xforms 规范中我们了解到,重复索引应该始终更新到最后插入的行,但事实并非如此。当使用 ref 或 nodeset 属性进行重复时,重复索引会按预期更新。
演示这个的小例子:
<?xml version="1.0" encoding="UTF-8"?>
<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xf="http://www.w3.org/2002/xforms"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
xmlns:idc="http://www.inventivedesigners.com/xbl"
xmlns:exf="http://www.exforms.org/exf/1-0"
xmlns:saxon="http://saxon.sf.net/">
<xhtml:head>
<xhtml:meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<xhtml:title>Test</xhtml:title>
<xf:model id="m-default">
<xf:instance id="i-default">
<data xmlns="">
<repeat>
<id>1</id>
</repeat>
</data>
</xf:instance>
<xf:instance id="i-counter">
<form xmlns="">
<counter>1</counter>
</form>
</xf:instance>
<!-- bindings -->
<xf:bind nodeset="repeat" id="repeat-bind" />
</xf:model>
</xhtml:head>
<xhtml:body style="width: 80%; margin-left: auto; margin-right: auto;">
<xhtml:table style="border: 1px solid black; margin-top: 50px;">
<xhtml:tbody>
<xf:repeat id="my_repeat" bind="repeat-bind">
<xhtml:tr>
<xhtml:td>
<xf:output ref="id" />
</xhtml:td>
</xhtml:tr>
</xf:repeat>
</xhtml:tbody>
</xhtml:table>
<xf:trigger>
<xf:label>Insert</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue value="number(.) + 1" ref="instance('i-counter')/counter"/>
<xf:insert position="after" nodeset="repeat" at="index('my_repeat')"/>
<xf:setvalue value="instance('i-counter')/counter" ref="repeat[last()]/id"/>
</xf:action>
</xf:trigger>
<fr:xforms-inspector/>
</xhtml:body>
</xhtml:html>
如果你按四次按钮,你会看到顺序是 1,4,3,2 而我们期望的是 1,2,3,4。在 repeat 上使用 ref 属性时,输出符合预期。
我用 Orbeon 4.4 和最新的 4.8 对此进行了测试,但行为是相同的。使用 bind 和 ref 有什么区别?
我更新了 github issue 并解释了它发生的原因。
作为解决方法,您可以使用 xf:setindex
在数据中插入新节点后显式设置重复索引。