簡體   English   中英

嘗試在XPage上使用'executeOnServer'從Javascript觸發SSJS

[英]Trying to trigger SSJS from Javascript using 'executeOnServer' on an XPage

我有一個相當長的,帶有標簽的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容器來創建“錨”,並縮小頁面中要評估,讀取提交或執行的部分的范圍(考慮最佳性能的最佳實踐)。 因此, myForm是執行ID。 從根本上講,執行ID屬於一個包含要觸發的事件處理程序的元素 例如,如果我將onautosave事件放置在myForm div之外,則不會觸發該事件。 如果您一點也不在乎(不好!),則可以刪除傳遞給XSP.partialRefreshPost方法調用中的對象的execId: '#{id:myForm}'屬性,此時,無論xsp如何,它都可以工作組件排列。

此外,通過XSP.partialRefreshPost您可以決定是否要部分刷新頁面的任何元素。 我將#{id:inputStamp}放進#{id:inputStamp}以便您可以看到輸入字段被觸發自動保存后產生的文本所填充。 如果您知道不必顯示由於服務器端方法評估而導致的任何DOM更改,則可以指定一個空字符串(例如XSP.partialRefreshPost('', ),這意味着在客戶端無norefresh但是,您仍然可以在操作完成時通過使用onComplete屬性來執行某些操作,如示例所示。

params屬性中,還有一個附加對象,該對象具有一個屬性,該屬性定義您要觸發的操作的ID: { '$$xspsubmitid' : '#{id:eventAutoSave}' }

總之,上述代碼每5秒將:

  1. 在Domino控制台上打印一些文本,以向您顯示該事件是在服務器端評估的
  2. 在圖章上填寫印章和執行日期
  3. 方法運行的時間在瀏覽器控制台上打印

沒有其他依賴項或摘要。 開箱即用。

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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM