Как я могу отложить загрузку содержимого UpdatePanel до тех пор, пока страница не отобразится?

Старая рука в ASP.NET, новая для UpdatePanel. У меня есть страница отчетов, которая выполняет довольно длинный SQL-запрос... сейчас занимает около 10 секунд. Я хотел бы, чтобы моя страница полностью отображалась с некоторым заполнителем (загрузка...), а затем заставляла UpdatePanel запускать процесс создания отчетов, отнимающий много времени, и отображать отчет по завершении.

Итак... моя теория состоит в том, чтобы использовать RegisterStartupScript(), чтобы сбросить это значение и удалить строку из GetPostBackEventReference(), чтобы запустить обновление UpdatePanel. Возникают некоторые проблемы:

1) Могу ли я на самом деле использовать GetPostBackEventReference с UpdatePanel или мне нужно запустить его каким-либо другим способом? Использовать этот метод для кнопки внутри панели обновления?

2) Какое событие вызывается, когда ссылкой обратной передачи является UpdatePanel? Это мне не понятно. Я должен позвонить где-нибудь мой код привязки данных! Опять же, может быть, мне нужно использовать кнопку внутри?

4 ответа

Решение

Я должен был сделать что-то очень похожее в последнее время, вот как я это сделал (правильно или неправильно):

Уловка - "Скрытый Асинхронный Запуск Обратной связи".

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

НТН.

Обновляя это с моим решением, я собрал воедино в основном из первого ответа выше.

Мне нужно загрузить свою страницу, а затем начать загружать контент для панели обновления. Панель вызывает некоторые веб-сервисы, и мы не хотим, чтобы вся страница зависала в случае, если удаленный сервер не отвечает. Мы тоже не хотим ждать.

Мой 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>

Мой код за фрагментами:
В 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

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

Упрощение очень полезного более раннего ответа 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() ниже:)

Например, чтобы вызвать это после загрузки страницы (согласно исходному вопросу), я просто добавил вызов, чтобы вызвать вышеуказанную строку кода в качестве параметра onload для основного тега Body таким образом:

<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://stackru.com/questions/26978112/execute-javascript-only-on-page-load-not-postback-sharepoint
             var ret = '<%= Page.IsPostBack%>' == 'True';
             return ret;
        }
        . . .
    </script>
</body>

Попробуйте что-то вроде этого (не проверено).

Установите UpdateMode для UpdatePanel Условно.

Добавьте это к вашему <head> раздел:

<script type="text/javascript">

    window.onload = __doPostBack('UpdatePanel1', ''); // Replace UpdatePanel1 with the ID of your UpdatePanel

</script>
Другие вопросы по тегам