Ereignisse in jQuery nach Ajax-Update (Updatepanel) neu binden


80

Ich habe mehrere Eingabe- und Optionselemente auf meiner Seite, an die jeweils (fast) ein Ereignis angehängt ist, um Text auf der Seite zu aktualisieren, sobald sie sich ändern. Ich benutze jQuery, was wirklich sehr, sehr cool ist :)

Ich verwende auch das Microsoft Ajax- Framework und verwende das UpdatePanel. Der Grund, warum ich das tue, ist, dass bestimmte Elemente auf der Seite basierend auf einer serverseitigen Logik erstellt werden. Ich möchte nicht wirklich erklären, warum ich das UpdatePanel verwende - auch wenn es (mit einigem Aufwand) umgeschrieben werden könnte, um nur jQuery zu verwenden, möchte ich dieses UpdatePanel immer noch.

Sie haben es wahrscheinlich erraten - sobald ich ein Postback auf dem UpdatePanel habe, funktionieren die jQuery-Ereignisse nicht mehr. Ich hatte dies tatsächlich erwartet, da das "Postback" nicht wirklich ein neues Postback ist, so dass mein Code in document.ready, der die Ereignisse bindet, nicht erneut ausgelöst wird. Ich habe meinen Verdacht auch bestätigt, indem ich ihn in den jQuery-Hilfebibliotheken nachgelesen habe.

Wie auch immer, ich habe das Problem, meine Steuerelemente erneut zu binden, nachdem das UpdatePanel das DOM aktualisiert hat . Ich benötige vorzugsweise eine Lösung, bei der der Seite keine weiteren .js-Dateien (jQuery-Plug-Ins) hinzugefügt werden müssen, sondern nur die Nachaktualisierung des UpdatePanels, bei der ich einfach meine Methode aufrufen kann, um alle Formularelemente neu zu binden .


Dies ist dieser Frage sehr ähnlich: stackoverflow.com/questions/256195/…
Dan Herbert

Antworten:


85

Da Sie ASP.NET AJAX verwenden, haben Sie Zugriff auf einen pageLoadEreignishandler, der jedes Mal aufgerufen wird, wenn die Seite von einem UpdatePanel vollständig oder teilweise zurückgesendet wird. Sie müssen nur die Funktion in Ihre Seite einfügen, es ist keine Verbindung erforderlich.

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

1
Kein Problem - das ist übrigens nur eine Möglichkeit. Wenn Sie mehr Flexibilität benötigen, überprüfen Sie das Ereignis endRequest in der PageRequestManager-Klasse.
Phil Jenkins

Genial! Ich habe mein jquery $ (Dokument) bereits durch Ihr pageLoad (ohne den if-Block) ersetzt und es hat mein Problem gelöst!
Chris

10
Achtung: Auf Seite wird nur eine "pageLoad" -Funktion ausgeführt - die zuletzt definierte. Wenn sich also Aktionen, die ausgeführt werden müssen, auf verschiedenen Steuerelementen befinden, gibt es einfachere Möglichkeiten, das erforderliche Verhalten zu erreichen - wie "Sys.Application.add_load".
Paulius

23

Oder Sie können die Live-Funktionalität von jQuery über die on()Methode überprüfen .


Dies war die beste Lösung für mich, da ein Großteil meines jQuery-Markups in mehreren Benutzersteuerelementen auf der Seite enthalten ist.
Kyle B.

1
Kannst du ein Beispiel mit Datepicker posten?
Perica Zivkovic

Ich habe nur "Ein" zum Binden an eine Dropdown-Liste in einem Bereich verwendet, der asynchrone Post-Triggerung ausführt. Es hat nicht funktioniert, bis ich auch die Antwort oben von @Phil Jenkins aufgenommen habe. Ich bin mir nicht sicher, ob es einen Unterschied macht, ob es sich um einen asynchronen oder einen vollständigen Beitrag handelt, aber das ist ein. Binder handhabte es nicht nach dem Post zurück.
Casey

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

14

Ab jQuery 1.7 wird empfohlen, die .on () -Syntax von jQuery zu verwenden .

Stellen Sie jedoch sicher, dass Sie das Ereignis für das Dokumentobjekt und nicht für das DOM-Objekt selbst einrichten . Dies wird beispielsweise nach dem UpdatePanel-Postback unterbrochen :

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

... weil die ': Eingänge' neu geschrieben wurden. Tun Sie dies stattdessen:

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

Solange das Dokument vorhanden ist, lösen alle Eingaben (einschließlich der Eingaben aus UpdatePanel-Aktualisierungen) den Änderungshandler aus.


Genial ! (das Dokument) funktionierte wunderbar mit den folgenden .... $ (Dokument) .on ('click', '# tagsAdd', function (), egal wie viele Update-Panels ich habe, die den Inhalt der Seite aufteilen :) Thx
Martin Sansone - MiOEE

9

Verwenden Sie den folgenden Code

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

Sie können jQuery und Ereignisdelegierung verwenden. Verknüpfen Sie Ereignisse grundsätzlich mit Containern und nicht mit jedem Element und fragen Sie das event.target ab und führen Sie das darauf basierende Skript aus.

Es hat mehrere Vorteile, da Sie das Code-Rauschen reduzieren (kein erneutes Binden erforderlich). Dies schont auch den Browserspeicher (weniger im DOM gebundene Ereignisse).

Kurzes Beispiel hier .

jQuery-Plugin für einfache Ereignisdelegierung.

PS Ich bin mir zu 99% sicher, dass die Delegierung bei der nächsten Version im jQuery-Kern sein wird.


5

Verwenden Sie den folgenden Code. Sie müssen überprüfen, ob das Steuerelement den Datenpicker verwendet:

    <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>

In das "if" können Sie den Code einfügen, den Sie jedes Mal ausführen müssen, wenn das Updatepanel AsyncPostBack ausführt.


2

Binden Sie Ihre Ereignisse mit der neuen Live-Methode von jQuery. Es bindet Ereignisse an alle Ihre gegenwärtigen und auch an alle zukünftigen Elemente. Cha ching! :) :)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.