Enviar datos asíncronos a un control fuera de un UpdatePanel

8. December 2009 17:48 by Oscar.SS in Desarrollo Web  //  Tags:   //   Comments (6)

Es posible que a muchos este título les suene a chino, y quizás también, no sea un caso que se de muy a menudo. Pero opino que es una característica que debemos conocer para tener más control sobre las aplicaciones ASP.NET AJAX.

 

El problema

Comenzemos plantenado el problema. Cuando utilizamos AJAX Extensions en una aplicación ASP.NET sabemos que en la respuesta asíncrona del servidor solo se envía de vuelta al cliente web una porción muy pequeña de HTML. Exactamente, solo se envía el HTML necesario para actualizar los controles que se encuentran dentro de un UpdatePanel, es lo que se conoce como repintado parcial. ¿Pero que ocurre si queremos, en algunas ocasiones, actualizar un control que se encuentra fuera de un UpdatePanel?. Es decir, ¿como podemos decirle al servidor que envíe otros datos además del HTML del repintado parcial?.

Veámoslo con un pequeño ejemplo.

    <div>
        
<asp:TextBox ID="TextBox1" runat="server">
            
</asp:TextBox><asp:Button ID="Button1" runat="server" Text="Button" 
            onclick
="Button1_Click" />
        <
br />
        <
br />
    
<!-----------Sección que se actualiza por AJAX (repintado parcial)--------------->
        
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
            
<ContentTemplate>
                
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
            
</ContentTemplate>
            
<Triggers><asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" /></Triggers>
        
</asp:UpdatePanel>
    
<!-------------------------------------------------------------------------------->    
        
<br />
        <
br />
        <
asp:Label ID="Label2" runat="server" Text="Label"></asp:Label>
    
</div>

 

¿Que tenemos aquí?. Tenemos un TextBox donde el usuario introducirá su nombre y tenemos dos Labels que mostrarán un saludo al usuario cuando hagan Click sobre el Button. Como podemos observar uno de los Labels se encuentra dentro de un UpdatePanel y el otro fuera. El que esta dentro se aprovechará de la funcionalidad de AJAX para actualizar su contendido de manera asíncrona.

Añadamos código para manejar el evento del Button y veamos que sucede.

 

        protected void Button1_Click(object sender, EventArgs e)
        {
            
string datosEnviados "Hola " + TextBox1.Text;

            
Label1.Text datosEnviados;
            
Label2.Text datosEnviados;
        
}

 

Al ejecutarse el evento vemos que solo se actualiza el Label1. El Label2 no se entera de nada. ¿Porque?.

Ya lo hemos comentado ante. El servidor solo está enviando al cliente el HTML necesario para actualizar los controles que se encuentran dentro del UpdatePanel.Repito la pregunta, ¿como podemos decirle al servidor que envíe otros datos además del HTML del repintado parcial?.

 

La solución

Cambiamos el código del evento del Button por el siguiente:

            string datosEnviados "Hola " + TextBox1.Text;
            
Label1.Text datosEnviados;

            
ScriptManager1.RegisterDataItem(Label2, datosEnviados);

El método RegisterDataItem() del ScriptManager envía datos en una llamanda asíncrona a los controles que se encuentran fuera del UpdatePanel. Ahora debemos manegar el siguiente evento en el cliente.

    <script type="text/javascript" language="javascript">
        Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(RecogerDatosHandler)
;

        function 
RecogerDatosHandler(sender, args) {
            
var datos args.get_dataItems();
            
$get("Label2").innerHTML datos["Label2"];
        
}
    </script>

En primer lugar obtenemos una instancia de la clase Sys.WebFroms.PageRequestManager que es la encargada de actualizar los controles que se encuentran dentro del UpdatePanel. Antes de que esta actualización ocurra, gestionamos el evento pageLoading() y recogemos los datos enviados desde el servidor para actualizar el Label2.

Hemos creado nuestro propio manejador del evento, RecogerDatosHandler(), que por medio del la colección args podemos acceder a los datos enviados desde el servidor.

Nota: La definición del script cliente anterior debe colocarse después de la definición del controls ScriptManager, de lo contrario nos dará un error diciendo que el espacio de nombres Sys no está definico aún, ¡como es lógico!.

 

Comments (6) -

jota
jota
7/28/2011 3:56:39 PM #

Muchas gracias por el aporte. es muy útil y te hago una pregunta: Si lo que quiero enviar no es la propiedad "Text" de un control Label sino en cambio la propiedad, por decir algo, "Enabled" ¿Cómo el RegisterDataItem() debe ser utilizado?

Óscar.SS
Óscar.SS
7/28/2011 6:14:23 PM #

Hola Jota:

Fíjate en la definición del método RegisterDataItem (msdn.microsoft.com/es-es/library/bb301423.aspx).

public void RegisterDataItem(
    Control control,
    string dataItem,
    bool isJsonSerialized
)

Como puedes ver, la propiedad dataItem siempre es de tipo System.String, por lo tanto los datos siempre debes mandarlos como una cadena. Luego en el código cliente, bien por JQuery o por JavaScript asignas esta cadena a la propiedad del control HTML que quieras modificar.

Si desde el servidor enviamos la cadena "disable" para deshabilitar o habilitar un botón, en el código cliente podríamos hacer algo como:

function RecogerDatosHandler(sender, args) {
            var datos = args.get_dataItems();
            $("input[type=submit]").attr("disabled", datos);
        }

Espero haberte ayudado, si no es así, vuelve a preguntar Smile

Un saludo.

toniogago
toniogago
12/8/2011 11:47:34 PM #

Muchas gracias por el aporte. Me valió de mucho.

Tenía una Master Page de por medio y sólo tuve que añadir a los nombres de los campos "ctl00_". Estoy pensando en generar el script dinámicamente para que me sirva para más controles.

un saludo.

Oscar.SS
Oscar.SS
12/9/2011 7:49:39 AM #

Hola Toniogago.

Celebro que te sirva de ayuda. Y muchas gracias a ti también por tu aporte.

Un saludo

Hildeberto
Hildeberto
11/20/2012 6:48:23 PM #

Hola a ver si me pueden ayudar, tengo un boton dentro de un updatepanel  y quiero que este boton haga que un label que esta fuera del updatepanel  sea visible=true, muchas gracias si alguien me puede ayudar

Oscar.SS
Oscar.SS
11/20/2012 9:33:13 PM #

Hola Hildeberto,

Fíjate en el comentario de arriba a la pregunta de Jota, ahí esta explicado, tú caso es muy parecido al suyo.

Un saludo

Recent Comments

Comment RSS

Month List