尝试使用';从Javascript触发SSJS;executeOnServer';在XPage上
我有一个相当长的选项卡式XPage表单,由访问者填充,我想每隔几分钟在后端自动保存一次 整个表单表示一个托管bean,我可以通过调用尝试使用';从Javascript触发SSJS;executeOnServer';在XPage上,javascript,xpages,javabeans,xpages-ssjs,autosave,Javascript,Xpages,Javabeans,Xpages Ssjs,Autosave,我有一个相当长的选项卡式XPage表单,由访问者填充,我想每隔几分钟在后端自动保存一次 整个表单表示一个托管bean,我可以通过调用 portfolio.save(sessionScope.unid,false) 我找到了杰里米·霍奇(Jeremy Hodge)的这篇优秀文章(很好,老技巧经得起时间的考验!),解释了这项技术 然后我找到了Paul Calhoun在论坛上的回复,其中描述了如何使用带有计时器的技术来触发常规文档保存 我已经在我的XPage上实现了这项技术,但是SSJS根本没有
portfolio.save(sessionScope.unid,false)
我找到了杰里米·霍奇(Jeremy Hodge)的这篇优秀文章(很好,老技巧经得起时间的考验!),解释了这项技术
然后我找到了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'命令并手动添加了额外的参数-只是试图隔离问题)
非常感谢您对这个问题的深入了解(并且指出了正确的方向!)。Terry,这只是一个提示,您是否查看了浏览器控制台以查看是否抛出了任何错误(来自客户端代码)?您是否启用了错误日志以查看SSJS/Java代码中是否抛出了错误?Terry,这只是一个提示,您是否查看了浏览器控制台以查看是否抛出了任何错误(来自客户端代码)?您是否启用了错误日志以查看SSJS/Java代码中是否抛出错误?请确保引用了正确的id。下面是一个简单的工作示例(没有executeOnServer函数和计时器逻辑)。该代码在页面完成加载后运行:
<xp:scriptBlock id="scriptBlockAutoSave">
<xp:this.value><![CDATA[
XSP.addOnLoad(function(){
executeOnServer('#{javascript:getComponent('autoSave').getClientId(facesContext)}');
});
]]></xp:this.value>
</xp:scriptBlock>
确保引用了正确的id。下面是一个简单的工作示例(没有executeOnServer函数和计时器逻辑)。该代码在页面完成加载后运行:
<xp:scriptBlock id="scriptBlockAutoSave">
<xp:this.value><![CDATA[
XSP.addOnLoad(function(){
executeOnServer('#{javascript:getComponent('autoSave').getClientId(facesContext)}');
});
]]></xp:this.value>
</xp:scriptBlock>
它实际上比您找到的代码片段要简单得多(您可以删除所有这些)。。。
考虑下面的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());
}
}
公共类PortfolioBean实现可序列化{
私有静态最终长serialVersionUID=1L;
私有映射数据=新HashMap();
公共地图getData(){
返回数据;
}
public void autoSave(字符串unid,布尔值){
System.out.println(“unid是“+unid+”,something是“+something”);
数据放置(“盖章”,“自动保存在”+新日期());
}
}
以及以下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
容器来创建一个“锚”,并缩小页面中被评估、读取、提交或执行的部分(考虑到最佳性能的最佳实践)<因此,code>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秒,上述代码将:
没有额外的依赖项或代码段。它的工作原理与开箱即用的一样。它实际上比您找到的代码段要简单得多(您可以删除所有这些)。。。 考虑下面的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());
}
}
公共类PortfolioBean实现可序列化{
私有静态最终长serialVersionUID=1L;
私有映射数据=新HashMap();
公共地图getData(){
返回数据;
}
public void autoSave(字符串unid,布尔值){
System.out.println(“unid是“+unid+”,something是“+something”);
数据放置(“盖章”,“自动保存在”+新日期());
}
}
以及以下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
容器来创建一个“锚”,并缩小页面中被评估、读取、提交或执行的部分(考虑到最佳性能的最佳实践)因此,myForm
是执行id。执行id必须属于包含要启动的事件处理程序的元素。例如,如果我将放在自动保存上