2014-09-11 2 views
0

У меня есть страница контента ASP с тремя сетками в одной UpdatePanel и отдельная кнопка обновления, связанная с каждой сеткой. Когда страница загружается, сетки пусты. Если я затем каждый раз нажимаю каждую кнопку обновления, по одному, и ждут между каждым шагом, все три сетки будут заполняться правильно.Нажмите несколько кнопок с RegisterStartupScript

В моей первой версии этой страницы я предварительно заполнил сетки перед рендерингом начальной загрузки страницы. Тем не менее, каждая сетка медленно обновляется, и я хочу улучшить пользовательский интерфейс - начальная нагрузка заняла около 30 секунд. Я думал, что могу AJAXify страницу, чтобы она сначала загружалась быстро (с пустыми сетками), тогда все три обновления обновляются независимо от Javascript, и каждая сетка заполняется, как только ее соответствующий вызов refresh возвращается, в любом порядке, в котором они оказались готов. Таким образом, пользователю не нужно ждать завершения всех трех, прежде чем, по крайней мере, некоторые данные будут доступны.

Если я хочу, чтобы автоматизировать начальное заполнение только одной сетки, я могу легко использовать эту технику:

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, но я получаю тот же результат с обоими этими вариантами.

ответ

0

От here, я нашел яваскрипт очереди событий, которая помогает мне делать то, что я хочу:

<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 только последняя кнопка завершит обновление, как раньше.

По сути, звонки обновления на самом деле не многопоточны; они выполняются последовательно. Тем не менее, я теперь удовлетворен опытом пользователей.