javascript - 尝试在 XPage 上使用 'executeOnServer' 从 Javascript 触发 SSJS

标签 javascript xpages javabeans xpages-ssjs autosave

我有一个相当长的选项卡式 XPage 表单供访问者填充,并且我希望每隔几分钟在后端自动保存一次。

整个表单代表一个托管 bean,我可以使用按钮手动从 bean 值填充/保存 Domino 文档,只需调用...

portfolio.save(sessionScope.unid,false)

我找到了 Jeremy Hodge 写的这篇优秀的文章(太棒了,旧的技巧经得起时间的考验!),它解释了这项技术......

http://xpages.info/XPagesHome.nsf/Entry.xsp?documentId=88065536729EA065852578CB0066ADEC

然后我找到了 Paul Calhoun 的论坛回复,其中描述了如何使用带有计时器的技术来触发常规文档保存...

https://www-10.lotus.com/ldd/xpagesforum.nsf/xpTopicThread.xsp?documentId=B5ECAEC50241A3EE85257B32008248FC

我已经在我的 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 秒,上面的代码就会:

  1. 在 Domino 控制台上打印一些文本,以表明该事件已在服务器端进行评估
  2. 在字段中填写盖章和执行日期
  3. 在浏览器控制台打印该方法运行的时间

没有额外的依赖项或片段。它的工作原理就像开箱即用一样。

关于javascript - 尝试在 XPage 上使用 'executeOnServer' 从 Javascript 触发 SSJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50489824/

相关文章:

Javabean Introspector - 我的列表中有什么?

java - 在Java bean中创建一个进程,获取输出并返回网页

javascript - django - 无法将选定的标签传递到js(ajax代码)

javascript - 使用 mapbox js,如何更改 map 的样式?

javascript - 使用 WebSocket 的 React Native 不起作用

xml - 如何在 XPages 中使用验证器验证复选框

javascript - 停止带有 promise 的 $interval 函数

html - 如何删除带有背景颜色的表格单元格分隔符

javascript - 我可以触发 xe :namepicker via csjs?

java - Spring 复合 bean ?