Решено было поставить просто OutputCache, но он был убран, скорее всего ввиду того, что данные обновлялись несколько чаще, чем происходило обновление кэша, потому, когда я преступил к работе – его уже не было. Кэшировались только запросы, хотя тоже не особо помогло.
Собственно – была поставлена задача сделать отложенную загрузку части страницы, и как – не важно, лишь бы ajax, догружающий на window.onload страницы ее часть, и решение было применимо при условии жесткой связи контролов страницы (которые следовало догружать) со страницами, настройками текущего пользователя и даже с контролами на MasterPage.
Итак, задание есть – реализовать нужно сегодня.
Первым делом решил погуглить, наткнулся на статью Гайдара Магданурова - Отложенная загрузка фрагментов страницы, но вариант подгружать контролы «вручную», не подходит для меня, т.к. необходимо сохранить его работоспособность, т.е. постбеки и связь с мастер-страницей, хотя в голове и мелькал изврат по созданию экземпляра не просто Page, а MyPage J, но это реально изврат.
Обходить через делегаты вызовы методов со страниц ну очень не хотелось, мне так посоветовали на http://inln.ru/Blog/post/Lazy-Load-Control.aspx
В итоге – был реализован расширенный UpdatePanel, позволяющий догружать часть страницы после загрузки с вызовом делегата, на обновлении панели, в котором можно размещать код, биндящий содержимое UpdatePanel.
Также этот UpdatePanel позволяет управлять порядком обновлений, т.е. можно выставить приоритеты обновления частей страницы.
Каким образом можно поставить на обновление части страницы:
<cms:DeferredUpdatePanelUpdatePriority="0" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<%=DateTime.Now.Millisecond %>
</ContentTemplate>
</cms:DeferredUpdatePanel>
<cms:DeferredUpdatePanelUpdatePriority="2" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<%= DateTime.Now.Millisecond %>
</ContentTemplate>
</cms:DeferredUpdatePanel>
Сначала загрузится первая панель, потом вторая, за это отвечает свойство UpdatePriority, чем оно выше – тем позденее панель обновится.
Но что делать, если нужно вывести именно данные? Тут на помощь приходит событие OnDeferredUpdated – оно вызывается, когда панель необходимо обновить, точнее – когда он сам хочет обновиться, а именно – при первой загрузке страницы.
Для теста на странице разместим даталист, выводящий нам все числа, от 1 до 200, но выводится они будут только после загрузки страницы, т.е. подгрузятся аяксом:
<cms:DeferredUpdatePanelID="defPanel" UpdatePriority="2" runat="server" UpdateMode="Conditional" OnDeferredUpdated="defPanel_OnDeferredUpdated" OnPreUpdatingJS="onPreUpdating" OnUpdatingJS="onUpdating" OnUpdatedJS="onUpdated">
<ContentTemplate>
<asp:DataList runat="server" RepeatColumns="20" ID="listNothing" Width="100%" BorderWidth="1" BorderStyle="Dotted" CellPadding="0" CellSpacing="0">
<ItemStyle Width="5%" BorderStyle="Groove" />
<ItemTemplate>
<%# Container.DataItem %>
</ItemTemplate>
</asp:DataList>
</ContentTemplate>
</cms:DeferredUpdatePanel>
Заметьте, что есть обработчик события обновления OnDeferredUpdated:
protectedvoid defPanel_OnDeferredUpdated(object sender, DeferredUpdatePanelEventArgs e)
{
List<int> list = new List<int>();
for (int i = 0; i < 100; i++)
list.Add(i);
listNothing.DataSource = list;
listNothing.DataBind();
}
Именно в нем то мы и биндим все необходимые данные. Возможно кто-то скажет – «Да это и так просто можно сделать на OnLoad+ пара скриптов», что же, он будет прав, но если таких панелей 3 на странице – то код уже становится некрасивым и на обладку у новичка уйдет от получаса до часа, так что – лучше просто иметь подобный контрол.
Какие плюсы у этого контрола:
- Не нужно все делать самому
- Есть обработчик обновления – отличается от OnLoadименно тем, что для каждого UpdatePanelон свой, т.е. есть проверка на ClientID
- Есть возможность задать порядок обновления
- Вызываются JavaScriptфункции для подготовки части страницы перед обновлением, во время обновления и после обновления, при чем в эти функции передаются сами апдейтпанели (чисто для удобства, сокращает 2 строки кода для каждого из событий)
- Названия функций прописывать в свойствах: OnPreUpdatingJS, OnUpdatingJS, и OnUpdatedJS.
- Сохраняется событийная модель!
- Сохраняется связь контрола со страницей, с другими контролами или мастер-страницами
- Переделывать практический ничего не нужно, максимум – переместить код из обного места в другое и все