2009-09-10 10 views
8

He creado una página que combina un jQuery UI datepicker en línea. Quiero iniciar una devolución de llamada al panel de actualización cuando el usuario hace clic en una nueva fecha para actualizar algunos datos. Ahora, esta página tiene varios paneles de actualización (no preguntes :)), así que necesito verificar qué panel de actualización recargó para hacer algunas cosas al lado del cliente. Estoy usando __doPostBack para hacer la devolución de datos y Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) {} para escuchar cuando se realiza una actualización.Error extraño al combinar un panel de actualización de ASP.NET con jQuery UI DatePicker

El problema es que en el FF la devolución de llamada me dice que no se trata de una operación asincrónica, y los datos que necesito para verificar qué panel de actualización hizo que la actualización sea nula.

Mi problema es que esto funciona bien en IE, pero no en ningún otro navegador, lo que podría deberse a dos cosas: IE entra en un modo raro que resuelve el problema (esto es lo que creo) o que IE tiene algunos tipo de soporte nativo para el panel de actualización que otros navegadores no.

He reducido el problema, y ​​produjo un testpage:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title>Test</title> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js "></script> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js "></script> 
</head> 
<body> 
    <form id="form1" runat="server"> 
    <asp:ScriptManager ID="ScriptManager1" runat="server" /> 

    <script type="text/javascript"> 
     function doAspNetPostback() { 
      __doPostBack('<%= hiddenOnSelectionChangedButton.ClientID %>', ''); 
     } 

     $(document).ready(function() { 
      /* Create the datepicker */ 
      buildDatepicker(); 
      /* Add callback-method for when the scriptmanager finished a request */ 
      Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(sender, args) { 
       /* Show the panelID - This is 'upd1|hiddenOnSelectionChangedButton' in IE as it should be, and null in Chrome/FF */ 
       alert(sender._postBackSettings.panelID); 
      }); 
     }); 

     function buildDatepicker() { 
      var dp = $("#datepicker").datepicker({ 
       onSelect: function(dateText, inst) { 
        /* Do a postback when someone clicks a date */ 
        doAspNetPostback(); 
       } 
      }); 
     }   
    </script> 

    <div id="datepicker"> 
    </div> 
    <asp:UpdatePanel UpdateMode="Conditional" ID="upd1" runat="server"> 
     <ContentTemplate> 
      <asp:Button ID="hiddenOnSelectionChangedButton" Text="Press me" runat="server" /> 
      <div id="lala" runat="server"> 
       Upd1 
      </div> 
     </ContentTemplate> 
    </asp:UpdatePanel> 
    </form> 
</body> 
</html> 

Firing este testpage en IE dará lugar a un cuadro de mensaje que muestra lo que se supone que, mientras se carga, en los resultados de FF o Chrome en un messagebox que dice "null" :)

He intentado todo tipo de cosas, pero no estoy seguro de lo que podría causar este comportamiento, ya que no soy tan profundo en el funcionamiento interno de jQuery o ASP .NET Ajax. Sin embargo, si paso por el código en FireBug lo suficientemente lento ... ¿Qué me lleva a pensar que podría ser un problema con la interoperabilidad entre las devoluciones de llamada de jQuery y las devoluciones de llamada Ajax de ASP.NET?

Cualquier ayuda o idea será muy apreciada.

Gracias.

[ACTUALIZACIÓN] Tim lo resolvió! ¡Muchas gracias! - También gracias a todos los que pasaron su tiempo tratando de resolver esto :)

Respuesta

4

Creo que mi encontrar este artículo de MSDN interesante: http://msdn.microsoft.com/en-us/magazine/cc163413.aspx

El artículo dice que "Sys.WebForms.PageRequestManager.getInstance() add_pageLoaded (." También se adhiere a UpdatePanel eventos completos.

también dispara cada vez que un devolución de llamada asincrónica lanzado el nombre de un control UpdatePanel haya finalizado y c ontent dentro de ese UpdatePanel se actualiza.

a continuación en el controlador se puede recorrer los updatedpanels con

var panels = args.get_panelsUpdated(); 
for (i=0; i < panels.length; i++) { alert(panels[i]); } 

que se desviaría lejos de usar las _ postBackSettings debido a la "_" denota la privacidad, y podrían dejar en futuras versiones de ASP .net ajax.

+0

Esto funciona. Simple y genial :) ¡Muchas gracias! – cwap

0

Un problema común con las combinaciones de AJAX y jQuery es que esta ...

$(document).ready(function() { 
     buildDatepicker(); 

ocurre sólo en la primera carga de la página. Si reemplaza el área de HTML que se ha visto afectada por buildDatapicker(); Perdiste los eventos que estaban adjuntos (incluso si lo reemplazaste con los mismos elementos).

Todo lo que necesita hacer es llamar buildDatepicker contra el HTML recién cargada ... y pase el elemento que se ha cargado sólo para asegurarse de que no se duplican ...

$(document).ready(function() { 
     buildDatepicker(document); 
... 

function buildDatepicker(element) { 
    var dp = $("#datepicker", element).datepicker({ 
     onSelect: function(dateText, inst) { 
      /* Do a postback when someone clicks a date */ 
      doAspNetPostback(); 
     } 
    }); 
}  

Ahora puede llamar a buildDatepicker (myNewlyLoadedElement); volver a vincular la funcionalidad del selector de datos.

+0

Bueno, el datepicker ya está fuera del ámbito de contenido del panel de actualización, por lo que no debería verse afectado. Intenté su solución, pero todavía muestra null en Firefox :( – cwap

0

Puede intentar usar datepicker para establecer un altField y comprobar que los cambios hagan una devolución de datos.

+0

Sí, parece que esa es la única manera de hacerlo :( – cwap

0

He intentado con tu código para reproducir el error y puedo reproducir el error. Y he llegado a la conclusión de que hay algún problema con jQuery/UpdatePanels.

Si reemplazo el botón con un LinkButton, puede ver que el enlace llama directamente a __doPostBack (...), exactamente la misma función con exactamente los mismos argumentos que está llamando. Y hacer clic en el botón de enlace funciona directamente, pero hacer clic en una fecha no funciona.

Eso significa que dentro de jQuery sucede algo que cambia el contexto. Pero no tengo idea de lo que sería eso.

0

Encontré otra secuencia de comandos hace un tiempo que he estado usando desde hace un tiempo y nunca he tenido ningún problema.

<script type="text/javascript"> 
     /* 
     [__doPostBackAsync] 
     Will send an async postback to the backend 
     */ 
     function __doPostBackAsync(eventName, eventArgs) { 
      var prm = Sys.WebForms.PageRequestManager.getInstance(); 

      //check first if the request queues have this item 
      if (!Array.contains(prm._asyncPostBackControlIDs, eventName)) { 
       prm._asyncPostBackControlIDs.push(eventName); 
      } 
      if (!Array.contains(prm._asyncPostBackControlClientIDs, eventName)) { 
       prm._asyncPostBackControlClientIDs.push(eventName); 
      } 
      __doPostBack(eventName, eventArgs); 
     } 
    </script> 

Todavía puede establecer manualmente una función de devolución de llamada exactamente como lo hace en su secuencia de comandos anterior.

También puede que tenga que agregar manualmente un controlador de recursos de script (No puedo recordar cuál) pero específicamente recuerdo haber tenido problemas para llamar a los respaldos de publicaciones asincrónicas y no asincrónicas. Espero que ayude.

+0

No funciona.Gracias por intentarlo :) – cwap

1

He solucionado varios problemas de sincronización con jQuery/Updatepanels utilizando el argumento ScriptMode = "Release" en el ScriptManager.

<asp:ScriptManager ID="scriptManager" runat="server" ScriptMode="Release"> 
    </asp:ScriptManager> 
+0

No funcionó, por desgracia :( – cwap

0

Parece que una condición de carrera, tratar UpdateMode = "condicional" y ChildrenAsTriggers = "false", reference.

+0

Didnt help, aunque estoy de acuerdo, parece una condición de raza :) – cwap

+0

fue un tiro en la oscuridad :( – slf

0

Sin embargo, si me paso a través del código en FireBug suficientemente lento que funciona

Oh? ¿Por qué no le das un segundo para resolverlo?

setTimeout(function(){alert(sender._postBackSettings.panelID);},1000); 
+0

Jeje ... Sí, lo intenté , pero no es realmente el tipo de solución que estoy buscando xD – cwap

0

Me gustó la respuesta de Tim, que rodea la idea de que debería estar usando args.get_PanelsUpdated() en el evento pageLoaded. Parece ser el medio apropiado para hacer lo que estás intentando hacer. Pruébelo, si no funciona, entonces tengo otra idea en la manga (aunque está algo sucia).

0

Pensé que esto era interesante, si agrega una alerta después del doPostBack, entonces FF no devuelve null.

function doAspNetPostback() { 

     __doPostBack('<%= hiddenOnSelectionChangedButton.ClientID %>', ''); 
     alert('<%= hiddenOnSelectionChangedButton.ClientID %>'); 
    } 
Cuestiones relacionadas