Как я могу отложить загрузку содержимого 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>
Замечания:
Важный параметр OnClick = скрытой кнопки - это то, что определяет функцию сервера для вызова!
На панели обновлений нет триггерных предложений или триггеров, я использую дочерние элементы управления, которые автоматически запускаются - в частности, событие 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>