单击带有RegisterStartupScript的多个按钮

本文关键字:按钮 RegisterStartupScript 单击 | 更新日期: 2023-09-27 18:21:29

我有一个ASP内容页面,在一个UpdatePanel中有三个网格,每个网格都有一个单独的刷新按钮。加载页面时,网格为空。如果我单击每个刷新按钮,一次一个,并在每个步骤之间等待,那么所有三个网格都将正确填充。

在这个页面的第一个版本中,我会在呈现初始页面加载之前预先填充网格。然而,每个网格刷新都很慢,我想改善用户体验——最初的加载大约需要30秒。我想我可以AJAX化页面,这样它首先可以快速加载(使用空网格),然后所有三次刷新都独立于Javascript启动,并且每个网格在其各自的刷新调用返回后立即填充,无论它们的准备顺序如何。这样,用户就不必等到所有三个都完成后,才能获得至少一些数据。

如果我只想自动化一个网格的初始填充,我可以很容易地使用这种技术:

if (!IsPostBack)            
    ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridA", "document.getElementById('" + btnRefreshGridA.ClientID + "').click();", true);

当只有一个长时间运行的报告我想发布时,我已经使用过很多次了,在这里它很好用。但这是一个我以前从未考虑过的场景——如果我尝试为多个网格这样做:

if (!IsPostBack)            
{
    ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridA", "document.getElementById('" + btnRefreshGridA.ClientID + "').click();", true);
    ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridB", "document.getElementById('" + btnRefreshGridB.ClientID + "').click();", true);
}

那么唯一完成的刷新是最后一次。我想我不应该感到惊讶,因为如果我手动复制它,并立即单击一个又一个刷新按钮,我会得到相同的结果——第一个AJAX调用似乎被放弃了。这就是发生的事情吗?

有可能完成我想要做的事情吗?协调多个独立的、同时进行的AJAX调用的正确方法是什么?我怀疑我根本不应该使用这些按钮,但当只涉及一个按钮时,我已经在这种方法上取得了很大成功。我尝试过将点击组合到一个脚本中,并尝试过将每个网格/按钮对包装在自己的UpdatePanel中,但这两种变体都得到了相同的结果。

单击带有RegisterStartupScript的多个按钮

从这里,我发现了一个javascript事件队列,它可以帮助我做我想做的事情:

<script type="text/javascript">
     Sys.Application.add_load(ApplicationLoadHandler)
     function ApplicationLoadHandler(sender, args) {
         var prm = Sys.WebForms.PageRequestManager.getInstance();
         if (!prm.get_isInAsyncPostBack()) {
             prm.add_initializeRequest(InitializeRequest);
             prm.add_endRequest(CompleteRequest);
         }
     }
     var myQueue = new Array();
     function InitializeRequest(sender, args) {
         var prm = Sys.WebForms.PageRequestManager.getInstance();
         if (prm.get_isInAsyncPostBack()) {// if it's working on another request, cache the current item that cause the request
             args.set_cancel(true);
             Array.add(myQueue, args.get_postBackElement());
         }
     }
     function CompleteRequest(sender, args) {
         if (myQueue.length > 0) {// fire corresponding event again of the item cached
             $get(myQueue[0].id).click();
             Array.removeAt(myQueue, 0);
         }
     }
     if (typeof (Sys) !== "undefined") Sys.Application.notifyScriptLoaded();
</script>

这也可以从代码隐藏中呈现,如下所示:

StringBuilder script = new StringBuilder();
script.Append("Sys.Application.add_load(ApplicationLoadHandler)'n");
script.Append("function ApplicationLoadHandler(sender, args) {'n");
script.Append("    var prm = Sys.WebForms.PageRequestManager.getInstance();'n");
script.Append("    if (!prm.get_isInAsyncPostBack()) {'n");
script.Append("        prm.add_initializeRequest(InitializeRequest);'n");
script.Append("        prm.add_endRequest(CompleteRequest);'n");
script.Append("    }'n");
script.Append("}'n");
script.Append("var myQueue = new Array();'n");
script.Append("function InitializeRequest(sender, args) {'n");
script.Append("    var prm = Sys.WebForms.PageRequestManager.getInstance();'n");
script.Append("    if (prm.get_isInAsyncPostBack()) {'n");
script.Append("    args.set_cancel(true);'n");
script.Append("    Array.add(myQueue, args.get_postBackElement());'n");
script.Append("    }'n");
script.Append("}'n");
script.Append("function CompleteRequest(sender, args) {'n");
script.Append("    if (myQueue.length > 0) {'n");
script.Append("        $get(myQueue[0].id).click();'n");
script.Append("        Array.removeAt(myQueue, 0);'n");
script.Append("    }'n");
script.Append("}'n");
script.Append("if (typeof (Sys) !== '"undefined'") Sys.Application.notifyScriptLoaded();");
ClientScript.RegisterStartupScript(this.GetType(), "EventQueue", script.ToString(), true);

不管添加这个队列脚本的方法是什么,我发现我需要在点击按钮时添加一个轻微的延迟来让他们排队:

ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridA", "setTimeout('"document.getElementById('" + btnRefreshGridA.ClientID + "').click();'",100);", true);
ClientScript.RegisterStartupScript(this.GetType(), "RefreshGridB", "setTimeout('"document.getElementById('" + btnRefreshGridB.ClientID + "').click();'",100);", true);

如果没有setTimeout,只有最后一个按钮才能像以前一样完成刷新。

从根本上讲,刷新调用实际上并不是多线程的;它们是串行执行的。然而,我现在对用户体验感到满意。