我有一个相当长的选项卡式 XPage 表单供访问者填充,并且我希望每隔几分钟在后端自动保存一次。
整个表单代表一个托管 bean,我可以使用按钮手动从 bean 值填充/保存 Domino 文档,只需调用...
portfolio.save(sessionScope.unid,false)
我找到了 Jeremy Hodge 写的这篇优秀的文章(太棒了,旧的技巧经得起时间的考验!),它解释了这项技术......
http://xpages.info/XPagesHome.nsf/Entry.xsp?documentId=88065536729EA065852578CB0066ADEC
然后我找到了 Paul Calhoun 的论坛回复,其中描述了如何使用带有计时器的技术来触发常规文档保存...
我已经在我的 XPage 上实现了该技术,但 SSJS 根本没有启动。 我什至放置了“onStart”和“onComplete”事件来验证一切是否按预期工作。计数器工作,控制台显示计时器,并且警报每 5 秒左右出现一次......但 SSJS 根本没有启动。
我的 eventHandler 完成这项工作...
<xp:eventHandler event="onfubar" id="autoSave" submit="false">
<xp:this.action><![CDATA[#{javascript:portfolio.save(sessionScope.unid,false);}]]>
</xp:this.action>
</xp:eventHandler>
...以及触发常规保存的事件处理程序(是的,我知道我已经删除了“executeOnServer”命令并手动添加了附加参数 - 只是试图隔离问题)...
<xp:eventHandler event="onClientLoad" submit="false">
<xp:this.script><![CDATA[
var executeOnServer = function () {
// must supply event handler id or we're outta here....
if (!arguments[0])
return false;
// the ID of the event handler we want to execute
var functionName = arguments[0];
// OPTIONAL - The Client Side ID that you want to partial refresh after executing the event handler
var refreshId = (arguments[1]) ? arguments[1] : "@none";
var form = (arguments[1]) ? XSP.findForm(arguments[1]) : dojo.query('form')[0];
// OPTIONAL - Options object contianing onStart, onComplete and onError functions for the call to the
// handler and subsequent partial refresh
var options = (arguments[2]) ? arguments[2] : {};
// Set the ID in $$xspsubmitid of the event handler to execute
dojo.query('[name="$$xspsubmitid"]')[0].value = form.id + ':' + functionName;
XSP._partialRefresh("post", form, refreshId, options);
}
var x = 0;
var form = document.forms[0];
t = new dojox.timing.Timer(3600);
t.onTick = function() {
x+=1;
console.info(x);
if(x > 4){
x = 0;
console.info("reset");
executeOnServer('autoSave','@none',{
onStart: function() { alert('starting!'); },
onComplete: function() { alert('complete!'); },
onError: function() { alert('DANGER WILL ROBINSON!'); }
});
}
}
t.onStart = function() {
console.info("Starting timer");
}
t.start();]]></xp:this.script>
</xp:eventHandler>
我知道我一定错过了一些东西,而且我可能正直视着它,但我就是不知道我哪里出了问题。
非常感谢您对这个问题的任何见解(以及正确的方向!)。
最佳答案
它实际上可以比您找到的片段简单得多(您可以删除所有这些)... 考虑以下 bean:
public class PortfolioBean implements Serializable {
private static final long serialVersionUID = 1L;
private Map<String, Object> data = new HashMap<String, Object>();
public Map<String, Object> getData() {
return data;
}
public void autoSave(String unid, Boolean something) {
System.out.println("The unid is " + unid + " and something is " + something);
data.put("stamp", "autosave at " + new Date());
}
}
以及以下 xsp 源代码:
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:div id="myForm" style="padding: 20px;">
<xp:eventHandler event="onautosave" id="eventAutoSave"
submit="false" action="#{javascript:portfolio.autoSave(sessionScope.unid, false)}" />
<p>Stamp</p>
<xp:inputText id="inputStamp" value="#{portfolio.data.stamp}" size="60" />
</xp:div>
<xp:scriptBlock value="
XSP.addOnLoad(function() {
window.setInterval(function() {
XSP.partialRefreshPost('#{id:inputStamp}', {
execId: '#{id:myForm}',
params: { '$$xspsubmitid' : '#{id:eventAutoSave}' },
onComplete: function() { console.log('complete at ' + new Date()); }
});
}, 5000);
});" />
</xp:view>
我创建了一个 myForm
容器来创建“ anchor ”并缩小页面中被评估、读取、提交或执行的部分(鉴于最佳性能的最佳实践)。因此,myForm
是执行 ID。 执行 ID 属于包含您要触发的事件处理程序的元素,这一点至关重要。例如,如果我将 onautosave
事件放置在 myForm
div 之外,则该事件将不会被触发。如果您不在乎(糟糕!),您可以删除传递给 XSP.partialRefreshPost
方法中的对象的 execId: '#{id:myForm}'
属性调用,此时,无论 xsp 组件的排列如何,它都会工作。
此外,使用 XSP.partialRefreshPost
您可以决定是否要部分刷新页面的任何元素。我放置了 #{id:inputStamp}
,以便您可以看到输入字段被触发自动保存所生成的文本所填充。如果您知道不必显示服务器端方法评估所导致的任何 DOM 更改,您可以指定一个空字符串(如 XSP.partialRefreshPost('',
) 以及意味着在客户端 norefresh
。但是您仍然可以在操作完成时使用 onComplete
属性执行某些操作,如示例所示。
在 params
属性中,有一个附加对象,其属性定义了要触发的操作的 id:{ '$$xspsubmitid' : '#{id:eventAutoSave} ' }
。
总之,每 5 秒,上面的代码就会:
- 在 Domino 控制台上打印一些文本,以表明该事件已在服务器端进行评估
- 在字段中填写盖章和执行日期
- 在浏览器控制台打印该方法运行的时间
没有额外的依赖项或片段。它的工作原理就像开箱即用一样。
关于javascript - 尝试在 XPage 上使用 'executeOnServer' 从 Javascript 触发 SSJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50489824/