Повторне прив'язування подій у jQuery після оновлення Ajax (updatepanel)


80

На моїй сторінці є кілька елементів введення та опцій, до кожного (майже майже) приєднана подія для оновлення тексту на сторінці, коли вони змінюються. Я використовую jQuery, що справді дуже класно :)

Я також використовую фреймворк Microsofts Ajax , використовуючи UpdatePanel. Причина, по якій я це роблю, полягає в тому, що певні елементи створюються на сторінці на основі певної логіки на стороні сервера. Я насправді не хочу пояснювати, чому я використовую UpdatePanel - навіть якщо його можна (можна з певними зусиллями) переписати на використання лише jQuery, я все одно хочу, щоб UpdatePanel.

Ви, мабуть, здогадалися - як тільки у мене з’явиться зворотний зв’язок на UpdatePanel, події jQuery перестають працювати. Я насправді очікував цього, оскільки "зворотний зв’язок" насправді не є новим зворотним зворотним зв’язком, тому мій код у document.ready, який пов’язує події, більше не запускатиметься. Я також підтвердив свою підозру, прочитавши це в бібліотеках довідки jQuery.

У будь-якому випадку, у мене залишається проблема повторного прив'язки елементів керування після того, як UpdatePanel закінчить оновлення DOM . Мені бажано потрібне рішення, яке не вимагає додавання більше файлів .js (плагіни jQuery) на сторінку, а щось таке просте, як можливість вловлювати оновлення UpdatePanel, де я можу просто викликати свій метод, щоб перев’язати всі елементи форми .


Це дуже схоже на це запитання: stackoverflow.com/questions/256195/…
Ден Герберт

Відповіді:


85

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

function pageLoad(sender, args)
{
   if (args.get_isPartialLoad())
   {
       //Specific code for partial postbacks can go in here.
   }
}

1
Не біда - це лише один із способів зробити це до речі. Якщо вам потрібна більша гнучкість, перевірте подію endRequest у класі PageRequestManager.
Філ Дженкінс,

Чудово! Я замінив свій jquery $ (документ) .вже на вашу pageLoad (без блоку if), і це вирішило мою проблему!
Кріс

10
Увага: на сторінці виконується лише одна функція "pageLoad" - остання визначена. Отже, якщо дії, які потрібно виконати, знаходяться на різних елементах управління - існують простіші способи досягнення необхідної поведінки - наприклад, "Sys.Application.add_load".
Павлій

23

Або ви можете перевірити останню функціональність jQuery в реальному часі за допомогою on()методу.


Це було найкращим рішенням для мене, оскільки більша частина моєї розмітки jQuery вкладена в декілька елементів керування користувачами на сторінці.
Кайл Б.

1
Ви можете розмістити приклад з datepicker?
Perica Zivkovic

Я просто використовував "увімкнено" для прив'язки до випадаючого списку всередині панелі, яка виконує асинхронну активацію публікації. Це НЕ працювало, поки я також включив відповідь вище від @Phil Jenkins. Я не впевнений, що це робить різницю, якщо це асинхронний пост або повний пост назад, але включений. в'яжучий не обробляв його після відправлення назад.
Кейсі

22
Sys.Application.add_load(initSomething);
function initSomething()
{
  // will execute on load plus on every UpdatePanel postback
}

14

Починаючи з jQuery 1.7, рекомендованим способом зробити це є використання jonga .on () синтаксису .

Однак переконайтеся, що ви встановили подію на об'єкт документа , а не на сам об'єкт DOM. Наприклад, це зламається після зворотного зв’язку UpdatePanel :

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

... тому що ": входи" були переписані. Зробіть замість цього:

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

Поки документ навколо, будь-які входи (включаючи вхідні дані з оновлення UpdatePanel) ініціюватимуть обробник змін.


Чудово! (документ) чудово працював, використовуючи наступне .... $ (document) .on ('click', '# tagsAdd', function () незалежно від того, скільки панелей оновлень я розбиваю вміст сторінки :) Thx
Мартін Сансоне - MiOEE

9

Використовуйте наступний код

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

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

Це має багато переваг у тому, що ви зменшуєте шум коду (не потрібно перев’язувати). Це також легше в пам'яті браузера (менше подій, пов'язаних у DOM.)

Швидкий приклад тут .

jQuery плагін для зручного делегування подій.

PS Я впевнений на 99%, що делегування буде в ядрі jQuery при наступному випуску.


5

Використовуйте наступний код, Вам потрібно перевірити, керування буде використовувати засіб вибору даних:

    <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

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

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


       }

            </script>

        </ContentTemplate>
    </asp:UpdatePanel>

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


2

Пов’яжіть свої події за допомогою нового методу jQuery «в реальному часі». Це пов’яже події з усіма вашими нинішніми елементами та всіма майбутніми також. Ча цзин! :)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.