单击带有RegisterStartupScript的多个按钮

时间:2014-09-11 16:12:13

标签: c# javascript ajax registerstartupscript

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

在我的第一个版本的本页中,我会在渲染初始页面加载之前预先填充网格。但是,每个网格刷新都很慢,我想改善用户体验 - 初始加载大约需要30秒。我以为我可以AJAXify页面,以便它首先快速加载(使用空网格),然后所有三个刷新都是独立于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中,但我对这两种变体都得到了相同的结果。

1 个答案:

答案 0 :(得分:0)

here,我找到了一个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,只有最后一个按钮会像以前一样完成刷新。

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