Перепривязывание событий в jQuery после обновления Ajax (updatepanel) - PullRequest
78 голосов
/ 19 ноября 2008

У меня есть несколько элементов input и option на моей странице, к каждому (ну почти) есть событие, прикрепленное для обновления некоторого текста на странице после их изменения. Я использую JQuery, который действительно очень круто :)

Я также использую Microsoft Ajax Framework, используя UpdatePanel. Причина, по которой я это делаю, заключается в том, что определенные элементы создаются на странице на основе некоторой серверной логики. На самом деле я не хочу объяснять, почему я использую UpdatePanel - даже если он может (может быть с большими усилиями) переписан для использования только jQuery Я все еще хочу эту UpdatePanel.

Вы, наверное, догадались - после того, как у меня появится постбек на UpdatePanel, события jQuery перестают работать. Я на самом деле ожидал этого, так как «обратная передача» на самом деле не новая обратная передача, поэтому мой код в document.ready, который связывает события, больше не будет запускаться. Я также подтвердил свое подозрение, прочитав его в справочных библиотеках jQuery.

В любом случае, у меня осталась проблема повторного связывания элементов управления после того, как UpdatePanel завершит обновление DOM . Я предпочтительно нуждаюсь в решении, которое не требует добавления большего количества файлов .js (плагинов jQuery) на страницу, но что-то столь же простое, как возможность перехватить 'afterupdating' UpdatePanel, где я могу просто вызвать свой метод для повторной привязки всех элементов формы .

Ответы [ 9 ]

83 голосов
/ 19 ноября 2008

Поскольку вы используете ASP.NET AJAX, у вас будет доступ к обработчику событий pageLoad, который вызывается каждый раз, когда страница отправляет ответ, будь то полный или частичный из UpdatePanel. Вам просто нужно добавить функцию на свою страницу, подключение не требуется.

function pageLoad(sender, args)
{
   if (args.get_isPartialLoad())
   {
       //Specific code for partial postbacks can go in here.
   }
}
23 голосов
/ 13 февраля 2009

Или вы можете проверить работоспособность последней версии jQuery с помощью метода on().

21 голосов
/ 20 ноября 2008
Sys.Application.add_load(initSomething);
function initSomething()
{
  // will execute on load plus on every UpdatePanel postback
}
14 голосов
/ 01 августа 2012

Начиная с jQuery 1.7, рекомендуемый способ сделать это - использовать синтаксис jQuery .on () .

Однако убедитесь, что вы установили событие для объекта document , а не для самого объекта DOM. Например, это сломается после обратной передачи UpdatePanel :

$(':input').on('change', function() {...});

... потому что ': input' был переписан. Сделайте это вместо:

$(document).on('change', ':input', function() {...});

Пока документ находится рядом, любые входные данные (в том числе из обновлений UpdatePanel) будут запускать обработчик изменений.

9 голосов
/ 29 июля 2009

Используйте следующий код

Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);

function pageLoaded(sender, args) {
    var updatedPanels = args.get_panelsUpdated();
    // check if Main Panel was updated 
    for (idx = 0; idx < updatedPanels.length; idx++) {
        if (updatedPanels[idx].id == "<%=upMain.ID %>") {
            rebindEventsForMainPanel();
            break;
        }
    }
}
8 голосов
/ 19 ноября 2008

Вы можете использовать jQuery и делегирование событий. По сути, подключайте события к контейнерам, а не к каждому элементу, и запрашивайте event.target и запускайте сценарий на его основе.

Он имеет несколько преимуществ в том, что вы уменьшаете шум кода (нет необходимости перепривязывать). это также проще в памяти браузера (меньше событий, связанных в DOM.)

Быстрый пример здесь .

Плагин jQuery для легкого делегирования событий.

P.S Я на 99% уверен, что делегирование будет в ядре jQuery в следующем выпуске.

5 голосов
/ 04 ноября 2010

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

    <script type="text/javascript" language="javascript">

         Sys.WebForms.PageRequestManager.getInstance().add_endRequest(addDataPicker); 
         function addDataPicker(sender, args)
         {
            var fchFacturacion = document.getElementById('<%= txtFechaFacturacion.ClientID %>');
            if (fchFacturacion != null) {
               $(fchFacturacion).datepicker({ onSelect: function () { }, changeMonth: true, changeYear: true, showOn: 'button', buttonImage: '../Imagenes/calendar.gif', buttonImageOnly: true});}
         } 

    </script>

     <asp:UpdatePanel ID="upEjem" runat="server" UpdateMode="Conditional">
       <ContentTemplate>
              <div id="div1" runat="server" visible="false">
                  <input type="text" id="txtFechaFacturacion" 
                      name="txtFechaFacturacion" visible="true"
                      readonly="readonly" runat="server" />
              </div>
       </ContentTemplate>
     </asp:UpdatePanel>
4 голосов
/ 12 января 2010

         <script type="text/javascript">
             function pageLoad() {

                 if (Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {


       }

            </script>

        </ContentTemplate>
    </asp:UpdatePanel>

в "если" вы можете поместить код, который вам нужно выполнять, каждый раз, когда панель обновления выполняет AsyncPostBack.

2 голосов
/ 12 марта 2010

Свяжите свои события, используя новый метод jQuery 'live'. Он свяжет события со всеми вашими нынешними элементами и со всеми будущими. Ча цзин! :)

...