【问题标题】:execute standby dialog from link从链接执行待机对话框
【发布时间】:2014-08-03 09:40:52
【问题描述】:

这是我所拥有的:Xpages 页面,它根据 url 参数按键填写表单。渲染最多可能需要 10 秒,我想让用户知道表单正在执行某些操作。

Fredrik Norling 做了一个很棒的待机对话框,当我在按钮上使用它时效果很好(保存) http://openntf.org/XSnippets.nsf/snippet.xsp?id=standby-dialog-custom-control (保存时在表单上使用部分 ID 更新)

如何通过电子邮件中的链接执行此脚本块? 有诸如 beforepageload 、 afturpageload 之类的选项,或者我应该使用 beforeRenderResponse 如果是这样,我该怎么做。

【问题讨论】:

  • 我首先想到的是为什么渲染表单需要大约 10 秒,看看是否可以显着减少。尤其是在页面在内存中之后——它应该比这快得多,除非你在页面加载时有大量的逻辑处理。
  • 我也会对这 10 秒的延迟感兴趣。取决于你在做什么,这似乎不正确。但是,有时当我将大量文档注入 Java Objecs 时,我确实会遇到这样的延迟......所以我可以看到它正在发生......取决于代码。
  • 另外 - 我认为有一篇关于修改该 sn-p 的帖子,因此它也适用于 PageLoad 而不是部分刷新.. 但我找不到对此的参考。
  • 嗯,这 10 秒只是第一次呈现此页面,第二次只有 6 秒,这可能是例外时间。

标签: xpages lotus-domino


【解决方案1】:

在做了一些实验之后,看起来你很难完成你想做的事情。您上面引用的事件都是服务器端事件,因此无法与用户客户端进行通信。 view.postScript 也不适用。

问题是(我假设)您的所有逻辑都在页面加载之前完成。因此,我认为实现这一点的唯一方法是延迟逻辑处理,直到页面加载后进行部分刷新。

您可以通过将所有逻辑移动到自定义控件,将该自定义控件添加到面板,然后在 XPage 的 onClientLoad 事件中,对面板进行部分刷新,这将触发待机功能自动地。

我模拟了一个我正在谈论的例子:

Xpage 代码

<xp:this.beforePageLoad><![CDATA[#{javascript:viewScope.showLogic = false}]]></xp:this.beforePageLoad>
<xp:panel id="panelLogic">
    <xc:logic id="logic"
        rendered="#{javascript:viewScope.showLogic == true;}">
    </xc:logic>
</xp:panel>
<xp:br></xp:br>
<xp:br></xp:br>


<xc:standby></xc:standby>


<xp:eventHandler event="onClientLoad" submit="true"
    refreshMode="partial" refreshId="panelLogic">
    <xp:this.action><![CDATA[#{javascript:viewScope.showLogic = true;}]]></xp:this.action>
</xp:eventHandler>
</xp:view>

上述代码的关键部分是在页面加载时将 viewScope 变量设置为“false”,然后在部分刷新之前将其设置为“true”。将其设置为 true 会取消隐藏逻辑自定义控件并允许其正常处理。

逻辑自定义控件

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

    <xp:text escape="true" id="computedField1">
        <xp:this.value><![CDATA[#{javascript:for (x=0;x<100000000;x++) {

}}]]></xp:this.value>
    </xp:text>
</xp:view>

我怀疑可能有更好的方法来做到这一点,但这种方法效果很好。

【讨论】:

    【解决方案2】:

    我会将 XPage 加载为空,并在页面的 onload 事件中单击一个隐藏按钮。 此按钮将执行一些服务器端 SSJS,这些 SSJS 将显示您要显示的控件。然后 Standby 小部件将负责其余的工作。用户将获得等待对话框。

     <xp:view xmlns:xp="http://www.ibm.com/xsp/core"
        xmlns:xc="http://www.ibm.com/xsp/custom">
    
        <xp:button value="Clickme" id="LoadWait"
            style="visibility:hidden;display:none">
            <xp:eventHandler event="onclick" submit="true"
                refreshMode="partial" refreshId="MainContent">
                <xp:this.action><![CDATA[#{javascript:viewScope.HideOnLoad=true}]]></xp:this.action>
            </xp:eventHandler>
        </xp:button>
        <xp:div id="MainContent">
            <xp:div>
                <xp:this.rendered><![CDATA[#{javascript:if(!viewScope.HideOnLoad){
    return false
    }else{
    return true
    }}]]></xp:this.rendered>
                <xp:div>
                    <xp:table>
                        <xp:tr>
                            <xp:td>
                                <xp:label id="label1">
    
                                <xp:this.value><![CDATA[#{javascript:var startTime = new Date().getTime();
    var elapsedTime = 0;
    var timeOutSeconds = 20;
    
    while ( elapsedTime < timeOutSeconds) {
      java.lang.Thread.currentThread().sleep(1000);
      //re-check condition here
    
      elapsedTime = (new Date().getTime() - startTime) / 1024;
    }
    
    return "Name1"}]]></xp:this.value></xp:label></xp:td>
                            <xp:td>
                                <xp:inputText id="inputText1"
                                    value="#{viewScope.Name}">
                                <xp:this.defaultValue><![CDATA[#{javascript:"test"}]]></xp:this.defaultValue></xp:inputText></xp:td>
                        </xp:tr>
                        <xp:tr>
                            <xp:td>
                                <xp:label value="Company" id="label2"></xp:label></xp:td>
                            <xp:td>
                                <xp:inputText id="inputText2"
                                    value="#{viewScope.Company}">
                                </xp:inputText></xp:td>
                        </xp:tr>
    
                    </xp:table></xp:div>
            </xp:div>
        </xp:div>
        <xc:standby></xc:standby>
        <xp:eventHandler event="onClientLoad" submit="false">
            <xp:this.script><![CDATA[//increase timeout value for long running XPage requests 
    

    dojo.onLoad(function(){ XSP.submitLatency = 600 * 1000;var id="#{id:LoadWait}";document.getElementById(id).click()}]]>

    要使代码正常工作,您需要将standby widget code 添加到名为“standby”的自定义控件中

    【讨论】:

    • 我在 Xpages 表单上有一个保存按钮,该按钮对执行等待对话框的 ID 进行了部分刷新,我想根据将由 URL 参数 KEY 填充的 ID 执行该按钮。我以为我可以在 beforepageload 上做到这一点,但这是不可能的。
    • 这几乎就是我在下面推荐的。
    【解决方案3】:

    这不是最佳实践,但您可以创建一个 XPage (XParent),其中只包含一个活动备用小部件(或任何加载指示器)和一个 iframe 到您实际想要向用户显示的 XPage (XChild)。 XParent 需要有一个 JavaScript 函数,名为 hideStandby(),它允许隐藏备用小部件。那么您只需将parent.hideStandby() 添加到XChild 的onClientLoad 事件中。使用此设置,当用户访问 XParent 时,备用小部件立即可见,并且 XChild 在 iframe 内的背景中加载。一旦加载完成,XParent 中的备用小部件就会从 XChild 中隐藏。如果您将 iframe 跨越整个页面(css = position:fixed;width:100%;height:100%;border:none;...),用户不会知道实际上涉及 2 个不同的页面。

    【讨论】:

    • 我想到了,但就像你说的那样不是最佳实践
    • @Palmilord:我建议使用这种方法,因为我认为渲染 XPage 的任何内容都需要 10 秒。这意味着时间会丢失,例如,在 beforePageLoad 事件中。但是,如果页面的某些部分在访问时立即显示并且只需要 10 秒来呈现所有内容,那么您可以简单地在 XPage 代码的顶部添加一个 scriptBlock 来创建备用小部件。这样,当页面开始加载时,小部件会弹出,最后您可以在 XPage 的 onClientLoad 事件中再次隐藏它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多