2008-11-19 20 views
76

Tengo varios elementos de entrada y opción en mi página, cada uno (casi) tiene un evento adjunto para actualizar el texto en la página una vez que cambian. Yo uso jQuery, que es realmente genial :)Reenlace de eventos en jQuery después de la actualización de Ajax (panel de actualización)

También uso el framework Microsofts Ajax, utilizando UpdatePanel. La razón por la que hago eso es porque ciertos elementos se crean en la página en función de alguna lógica del lado del servidor. Realmente no quiero explicar por qué uso el UpdatePanel, incluso si pudiera (con un poco de esfuerzo) volver a escribir para usar solo jQuery. Todavía quiero ese UpdatePanel.

Probablemente lo adivinó: una vez que tengo una devolución de datos en el UpdatePanel, los eventos de jQuery dejan de funcionar. De hecho, estaba esperando esto, ya que la "devolución de datos" no es realmente una nueva devolución, por lo que mi código en document.ready que ata los eventos no se volverá a activar. También confirmé mi sospecha leyendo en las bibliotecas de ayuda de jQuery.

De todos modos, me queda el problema de volver a vincular mis controles después de que UpdatePanel haya terminado de actualizar el DOM. Preferiblemente necesito una solución que no requiera agregar más archivos .js (complementos jQuery) a la página, sino algo tan simple como poder capturar la 'post-actualización' de UpdatePanel, donde puedo simplemente llamar a mi método para volver a vincular todos los elementos del formulario .

+0

Esto es muy similar a esta pregunta: http://stackoverflow.com/questions/256195/jquery-document-ready-and-updatepanels –

Respuesta

83

Dado que está utilizando ASP.NET AJAX, tendrá acceso a un controlador de eventos pageLoad, al que se llama cada vez que la página publica, ya sea completa o parcial desde un UpdatePanel. Solo necesita ingresar la función en su página, no se requiere conexión.

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

¡Lo tiene! Gracias :) –

+1

No hay problema, esa es solo una forma de hacerlo por cierto. Si necesita más flexibilidad, consulte el evento endRequest en la clase PageRequestManager. –

+0

¡Impresionante! Reemplacé mi jquery $ (documento). Listo con tu pageLoad (sin el bloque if) y resolvió mi problema. – Chris

8

Puede usar jQuery y delegación de eventos. Básicamente, enganche los eventos a los contenedores en lugar de a cada elemento y consulte el script de eventos.target y ejecutar en función de eso.

Tiene múltiples beneficios porque reduce el ruido del código (no es necesario volver a enlazar). Es también más fácil en la memoria del explorador (menos eventos vinculados en el DOM.)

Ejemplo rápido here.

jQuery plugin para facilitar la delegación de eventos.

P.S Estoy 99% seguro de que la delegación estará en el núcleo de jQuery en la próxima versión.

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

Esto funcionó muy bien para mí para hacer que un control jQuery ASP.Net funcione dentro de un panel de actualización – Earlz

+0

Gracias por proporcionar una solución para tener solo una función pageLoad (remitente, argumentos) en la página – SQueek

+0

La mejor solución, y funciona igual @ SQueek dijo, debido a un solo 'pageLoad (remitente, args)' en una página. – Pegues

23

O se puede comprobar la funcionalidad en vivo lo último de jQuery a través del método on().

+0

Esta fue la mejor solución para mí, ya que gran parte de mi marcado jQuery está encapsulado dentro de varios controles de usuario en la página. –

+1

¿puedes publicar un ejemplo con datepicker? –

+0

Whoah, mucho mejor que volver a enlazar en postback. ¡Gracias por el consejo! – Matt

9

Uso siguiente código

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; 
     } 
    } 
} 
4

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

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


     } 

      </script> 

     </ContentTemplate> 
    </asp:UpdatePanel> 

en el "si" se puede poner el código que necesita ejecutar cada vez que el UpdatePanel hace AsyncPostBack.

+0

Gracias @CIM, esta solución funcionó bien para mí ... –

2

Enlaza tus eventos usando el nuevo método 'en vivo' de jQuery. Se vinculará eventos a todos sus elementos presentes y todos los futuros también. Cha ching!:)

5

utilizar el siguiente código, es necesario para validar el control utiliza la datapicker:

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

A partir de jQuery 1.7, la forma recomendada de hacer esto es utilizar jQuery's .on() sintaxis.

Asegúrese, sin embargo, de que configure el evento en el documento documento objeto, no el objeto DOM en sí. Por ejemplo, Esto romperá después de la devolución de datos UpdatePanel:

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

... porque los han vuelto a escribir: 'entradas'. Hacer esto en su lugar:

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

Mientras que el documento es de alrededor, cualquier entrada (incluidos los de UpdatePanel refresca) activará el manejador de cambio.

+0

¡Impresionante! (el documento) funcionó de maravilla usando lo siguiente .... $ (document) .on ('click', '# tagsAdd', function() no importa cuántos paneles de actualización tengo dividiendo el contenido de la página :) Thx –

Cuestiones relacionadas