这就是我想做的事:的XPages事件代码执行两次而不是一次
在一个XPage我想有一个调用一些服务器端代码(Java Bean或SSJS)用户按当一个编辑框控件输入。这个主要的用例是,这个页面将从iPad上运行并附带一个蓝牙条形码扫描器。该扫描仪模拟键盘。用户将点击编辑框。然后他们将用扫描仪进行扫描,条码将与“输入”键一起输入。编辑框需要立即清除,以便进行下一次扫描,并且需要处理扫描的值。处理将对java bean执行各种后端处理,然后返回一条消息以显示在页面上。基本上是其中之一: 1.项目未找到,2.项目是可用和分配的,3.项目已分配,但你可以拥有它4.项目不可用
我有这个代码和整体的核心代码工作正常。我通常使用onchange事件,但由于我有这个问题,我转移到onkeypress事件。这是试图让它在IE中运行的尝试。这个目标再次只针对iPad/Safari,但我也希望能够在桌面浏览器上运行。我目前只与Chome一起测试。
在CSJS片编辑框的我有这样的代码:
var e = dojo.fixEvent(thisEvent);
if (e.keyCode == dojo.keys.ENTER) {
return true;
} else {
return false;
}
的想法是,我只是想打电话给SSJS上的Enter键。
下面是SSJS代码,它清除编辑框,处理值然后设置一对viewScope变量。
// Get the value off the page and put it in to the key variable
var key:String = getComponent("scanBox").getValue();
// clear the scanbox so it's ready for the next scan.
getComponent("scanBox").setValue("");
//Managed Bean to hold the last scan value - since the scanbox is cleared we do want to show the value
Scan.setLastScan(key);
// Managed Bean to process the item.
AddToJob.processItem(key);
viewScope.put("vsShowAssignPanel", true);
viewScope.put("vsShowMessagePanel", false);
SSJS代码被设置为部分更新页面的主要内容。我使用引导程序,并试图刷新页面上除顶部和底部导航栏外的所有内容。由于我在扫描后清除了值,编辑框本身在部分刷新区域中。
最后,这里的问题:
按钮的SSJS代码被运行两次。不是所有的原因,但可能90%的时间。我不会点击两次。我测试的方式是在我的桌面上使用Chrome,然后将值粘贴到该字段中,然后在键盘上按一次Enter。
如果我正在尝试扫描并指定带有条形码的项目。它首先运行良好。它会更新对象并将一个字段保存到后端NotesDocument中以将其标记为已分配。只是想要我想要的。但是第二次通过命中,它阻止了该项目已被分配,并给我回错信息。
经过大量的试验和错误之后,我相当确定JSF生命周期中的某些内容导致它运行两次。为什么我不知道。我不知道如何获得一次。
到目前为止我发现的唯一好的解决方法是在“AddToJob.processItem”方法中。 “AddToJob”是viewScope中的一个托管bean。在那里我存储并保留最后一个条码。然后我做一个检查,看看价值是一样的。如果是这样,那么我认为它在第二次运行并停止处理。
我已经在编辑控件的变化事件中使用了调用代码多年的基本概念。但那是在XPages Mobile Controls内部,有时候事情在那里的表现会有所不同。我试图重新编写这个应用程序来使用Bootstrap而不是XPages移动控件。
下面是编辑控件的完整XML标记(如果有帮助的话)。
<xp:inputText id="scanBox" styleClass="newTarget">
<xp:this.attrs>
<xp:attr name="placeholder" value="Tap to Scan..." />
<xp:attr name="autocorrect" value="off" />
</xp:this.attrs>
<xp:this.dojoAttributes>
<xp:dojoAttribute name="autocorrect" value="off" />
</xp:this.dojoAttributes>
<xp:eventHandler event="onkeypress" submit="true" refreshMode="partial" refreshId="mainPanel">
<xp:this.script><![CDATA[var e = dojo.fixEvent(thisEvent);
if (e.keyCode == dojo.keys.ENTER) {
return true;
} else {
return false;
}]]></xp:this.script>
<xp:this.action><![CDATA[#{javascript:// Get the value off the page and put it in to the key variable
var key:String = getComponent("scanBox").getValue();
// clear the scanbox so it's ready for the next scan.
getComponent("scanBox").setValue("");
//Managed Bean to hold the last scan value - since the scanbox is cleared we do want to show the value
Scan.setLastScan(key);
// Managed Bean to process the item.
AddToJob.processItem(key);
viewScope.put("vsShowAssignPanel", true);
viewScope.put("vsShowMessagePanel", false);}]]></xp:this.action>
</xp:eventHandler></xp:inputText>
任何信息表示赞赏。非常感谢你!!!
另一个非常简单的方法是在style:“display:none”的某处放置一个输入字段:-) –