【问题标题】:How can I defer loading UpdatePanel content until after the page renders?如何推迟加载 UpdatePanel 内容,直到页面呈现后?
【发布时间】:2011-04-22 03:12:38
【问题描述】:

ASP.NET 的老手,UpdatePanel 的新手。我有一个执行相当长的 SQL 查询的报告页面……现在大约需要 10 秒。我想做的是让我的页面完全呈现,并带有一些占位符文本(正在加载...),然后让 UpdatePanel 启动实际耗时的报告过程并在完成后呈现报告。

所以...我的理论是使用 RegisterStartupScript() 来启动它并从 GetPostBackEventReference() 中删除字符串以触发 UpdatePanel 更新。出现了一些问题:

1) 我可以通过 UpdatePanel 实际使用 GetPostBackEventReference 还是需要以其他方式触发它?在更新面板内的按钮上使用此方法?

2) 当回发引用是 UpdatePanel 时会触发什么事件?我不清楚。我必须在某处调用我的数据绑定代码!再说一次,也许我需要在里面使用一个按钮?

【问题讨论】:

    标签: javascript asp.net updatepanel


    【解决方案1】:

    我最近不得不做一些非常相似的事情,我是这样做的(对或错):

    诀窍是“隐藏的异步回发触发器”。

    <asp:UpdatePanel ID="upFacebookImage" runat="server">
       <ContentTemplate>
          <!-- Your updatepanel content -->
       </ContentTemplate>
       <Triggers>
          <asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
       </Triggers>
    </asp:UpdatePanel>
    <asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />
    

    然后从 JavaScript 中,每当您想触发异步回发时,您都可以这样做:

    __doPostBack('<%= hiddenAsyncTrigger.ClientID %>', 'OnClick');
    

    在我的示例中,我需要从特定的 JS 事件触发异步回发。但是您可以将其附加到准备好的文档中。

    我似乎记得尝试过@Marko Ivanovski 的方式,但由于某种原因它没有奏效。我认为您需要指定一个“可回发”控件(即按钮)来触发回发。

    HTH。

    【讨论】:

    • 宾果游戏,这成功了。不过稍作修改,因为我使用了 GetPostBackEventReference(btnTrigger, string.Empty);然后 RegisterStartupScript()。
    • 是的,如果你想触发一个特定的服务器端事件处理程序,那么是的——你需要这样做。就我而言,我只需要回发即可再次运行 Page_Load。很高兴它成功了。
    • 一个缺点...如果您手动回发,似乎不会触发 UpdateProgress 控件。
    • 有趣(在我的场景中不需要)。您实际上并不是 need UpdateProgress 控件 - 只需创建一个隐藏的占位符并在您触发异步回发时显示它。 UpdateProgress 控件(与许多其他 Web 窗体服务器控件一样)非常方便,但可以轻松替换。
    • 我只想说 style="display:none;"在 Button 上,而不是 Visible=false 很关键。使用 Visible=false 时,我能够触发回发(使用 GetPostBackEventReference),但它不是异步的。
    【解决方案2】:

    用我的解决方案更新这个,我主要从上面的第一个答案拼凑而成。

    我需要加载我的页面,然后开始为我的更新面板加载内容。面板调用一些 web 服务,我们不希望整个页面在远程服务器没有响应的情况下崩溃。我们也不想等待。

    我的 HTML:

    <asp:UpdatePanel ID="udpCheckout" runat="server" UpdateMode="Always">
            <ContentTemplate>
                <asp:Image ID="imgSpinner" runat="server" Visible="true" ImageUrl="~/images/ajax-loader.gif" />
                <br />
                <asp:Label ID="lblWait" runat="server" Visible="true" Text="Please wait..."></asp:Label>
                <asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" style="display:none;" />
            </ContentTemplate>
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="hiddenAsyncTrigger" EventName="Click" />
            </Triggers>
        </asp:UpdatePanel>
    

    我的 sn-ps 代码:
    在 page_load 中:

    ScriptManager.RegisterStartupScript(Me.Page, Me.Page.GetType, "LoadUpdate", GetPostBackEventReference(hiddenAsyncTrigger, String.Empty), True)
    

    还有按钮处理程序:

    Sub LoadUpdatePanels(ByVal o As Object, ByVal e As EventArgs) Handles hiddenAsyncTrigger.Click
            System.Threading.Thread.Sleep(5000)  'wait 5 seconds so I can see the page change
            imgSpinner.Visible = False
            lblWait.Text = "Content is now loaded."
            'udpCheckout.Update()
        End Sub
    

    这是我的测试,看看我是否可以让它工作。现在用真正的代码替换所有这些!

    【讨论】:

      【解决方案3】:

      试试这样的(未测试)

      UpdatePanelUpdateMode设置为Conditional

      将此添加到您的 &lt;head&gt; 部分:

      <script type="text/javascript">
      
          window.onload = __doPostBack('UpdatePanel1', ''); // Replace UpdatePanel1 with the ID of your UpdatePanel
      
      </script>
      

      【讨论】:

        【解决方案4】:

        简化 RPM1984 的非常有用的早期答案(感谢 ;))并展示一些我认为必要的调整和更多周边细节:

        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        
        <asp:UpdatePanel ID="upFacebookImage" runat="server">
            <ContentTemplate>
                <asp:PlaceHolder runat="server" ID="PlaceHolderMediaPrompts" />
                <asp:Button ID="hiddenAsyncTrigger" runat="server" Text="AsyncUpdate" OnClick="WasPage_Load" style="display:none;" />
            </ContentTemplate>
        </asp:UpdatePanel>
        

        注意:

        1. 隐藏按钮的重要OnClick=参数,这就是指定要调用的服务器函数!

        2. 更新面板中没有触发子句或触发器,我使用的是自动触发的子控件 - 特别是按钮 Click 事件。

        要从客户端 Javascript 触发它,您可以使用:

        document.getElementById("hiddenAsyncTrigger").click‌​();
        

        但是,我发现它有必要防止在后续页面加载时调用它(因为它会导致不必要的页面加载循环和随之而来的闪烁)。请参阅下面的整洁的小 IsPostBack() 检查 :)

        例如为了在页面加载后调用它(根据原始问题),我只是添加了一个调用来调用上面的代码行作为主要 Body-tag 的 onload-parameter 因此:

        <body onload="DoPostLoad();">
        ...  
            <script type="text/javascript">
                function DoPostLoad()
                {
                    if ( IsPostBack() != true ) // ***This is NEW and ESSENTIAL! ***
                        document.getElementById("hiddenAsyncTrigger").click();
                }
        
                function IsPostBack() { // Ref. https://stackoverflow.com/questions/26978112/execute-javascript-only-on-page-load-not-postback-sharepoint
                     var ret = '<%= Page.IsPostBack%>' == 'True';
                     return ret;
                }
                . . .
            </script>
        </body>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          • 2020-02-19
          • 2011-09-15
          • 1970-01-01
          • 2013-12-30
          • 2014-10-01
          • 2012-11-23
          相关资源
          最近更新 更多