2010-05-19 23 views
5

Ok: Tengo un UpdatePanel en una página aspx que contiene un marcador de posición único.Código de JavaScript dentro de UpdatePanel

Dentro de este marcador de posición Estoy agregando uno de una selección de controles de usuario dependiendo de ciertas condiciones externas (esta es una página de configuración).

En cada uno de estos controles de usuario hay una función javascript bindUcEvents() que vincula los diversos eventos de jQuery y javascript a botones y validadores dentro del control de usuario.

El problema que tengo es que el javascript de usercontrol no se reconoce. Normalmente, javascript dentro de un panel de actualización se ejecuta cuando el panel de actualización publica, sin embargo, nada de este código puede ser encontrado por la página (he intentado ejecutar la función manualmente a través de la consola de firebug, pero me dice que no puede encontrar la función).

¿Alguien tiene alguna sugerencia?

Cheers, Ed.

EDIT:

Cortado (pero funcional) ejemplo:

de marcado:

<script src="/js/jquery-1.3.2.min.js"></script> 
    <form id="form1" runat="server"> 
    <div> 

    <asp:ScriptManager ID="Script" runat="server" /> 

    <asp:Button ID="Postback" runat="server" Text="Populate" OnClick="PopulatePlaceholder" /> 

    <asp:UpdatePanel ID="UpdateMe" runat="server"> 
    <Triggers> 
     <asp:AsyncPostBackTrigger ControlID="Postback" EventName="Click" /> 
    </Triggers> 
     <ContentTemplate> 
      <asp:Literal ID="Code" runat="server" /> 
      <asp:PlaceHolder ID="PlaceMe" runat="server" /> 
     </ContentTemplate> 
    </asp:UpdatePanel> 
    </div> 
</form> 

C#:

protected void PopulatePlaceholder(object sender, EventArgs e) 
{ 
    Button button = new Button(); 
    button.ID = "Push"; 
    button.Text = "push"; 
    button.OnClientClick = "javascript:return false;"; 
    Code.Text = "<script type=\"text/javascript\"> function bindEvents() { $('#" + button.ClientID + "').click(function() { alert('hello'); }); } bindEvents(); </script>"; 
    PlaceMe.Controls.Add(button); 
} 

verá que el botón no poput el mensaje de alerta, aunque el código esté presente en la página.

Edit2:

Ok, sólo para que quede claro, el código de producción es significativamente más complejo que una sola función unido a un literal, y contiene un gran número de

<%= Control.ClientID %> 

los bits de código que será muy difícil de desglosar en funciones no específicas, y sin sentido, ya que cada uno de ellos solo se usa en un solo lugar (estamos hablando de validación muy específica y el disparador de popout extraño + algo de lógica).

+1

¿Puedes publicar parte del código fuente o generado? sin esto, es muy difícil de diagnosticar. – scunliffe

+0

seguro, simplemente tiendo a evitar hacerlo ya que hay bastante, intentaré cortarlo un poco –

+0

Has afirmado que tienes un montón de código, por lo que no está en el código subyacente. .. ¿Entonces donde esta? En el aspx? En un archivo js externo? ¿Cargado desde un archivo de base de datos/xml y leído por el código? – Stobor

Respuesta

8

Deshágase de ese control literal y use el ScriptManager para registrar su secuencia de comandos. Lo que está haciendo no funciona por la misma razón

window.document.getElementById('someId').innerHtml = "<script type=\"text/javascript\">alert('hey');</script>"; 

no funciona. Intente esto:

protected void PopulatePlaceholder(object sender, EventArgs e) 
{ 
    Button button = new Button(); 
    button.ID = "Push"; 

    button.Text = "push"; 
    button.OnClientClick = "return false;"; 


    string script = "function bindEvents() { $('#" + button.ClientID + "').click(function() { alert('hello'); }); } bindEvents();"; 

    ScriptManager.RegisterClientScriptBlock(this.Page, typeof(SomeClass), Guid.NewGuid().ToString(), script, true); 


    PlaceMe.Controls.Add(button); 
} 

Los parámetros para RegisterClientScriptBlock pueden necesitar cambiar, pero se entiende.

+3

la capacidad de mantenimiento se reduce a cero, aunque si hago esto: estamos hablando de 200 líneas de JS que hacen muchas cosas, la mayoría de las cuales usan el control clientIDs para hacerlo. ese tipo de código es muy difícil de mantener cuando está en el backend ... –

+1

. Entonces necesita refactorizar sus scripts. Esta es la forma correcta de hacer esto. Lo siento. –

+1

es decir, tendrá que volver a escribir las secuencias de comandos para que puedan colocarse en archivos js. Luego tendrá que llamar a ScriptManager.RegisterClientScriptBlock y ScriptManager.RegisterStartupScript según sea necesario. No hay forma de que consigas lo que intentas hacer sin llamadas al ScriptManager. Los scripts en ascx/aspx no son una buena práctica de todos modos y no ayudan al rendimiento. –

2

Agregue el administrador de scripts (Extensiones de Ajax) a su página y agregue las referencias de scrip dentro de ese administrador. El administrador cargará cada etiqueta de script en ajax-based-pageload (y no solo la carga inicial) - moverá todo el código de JavaScript necesario dentro del panel de actualización y ya casi habrá terminado.

<asp:ScriptManager ID="ScriptManager1" runat="server"> 
     <Scripts> 
      <asp:ScriptReference Path="../lib/jquery-1.2.6.pack.js" /> 

No leí la pregunta lo suficientemente bien (y sin la muestra). Ver mi nueva respuesta.

+1

Necesita un administrador de scripts para usar los paneles de actualización, y el código es todo interno para el control de usuario (incrustado en la página) ya que usa identificadores específicos del control, por lo que esto realmente no es útil. –

5

volver a ejecutar algunos js después de una actualización de pantalla ha disparado Siempre he utilizado este

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
    function(sender, args) { 
     //update whatever here 
    }); 

También si usted tiene cualquier referencia a elementos dentro del panel de actualización puede actualizar esas variables dentro de esa función también, de lo contrario, tendrás referencias antiguas que no funcionarán.

+0

Sí, eso lamentablemente solo funciona si el código está presente en la página original en primer lugar. Como estoy usando controles dinámicos y cargándolos a través de un UpdatePanel (es decir, a través de javascript), ¡las nuevas funciones de javascript no se reconocen como funciones! –

+0

Hmmm ... Sé que las evaluaciones no son lo mejor a lo que recurrir, pero ¿qué hay de hacer esta llamada dentro de la devolución de llamada de UpdatePanel enumerada anteriormente? ... // actualizar lo que sea aquí eval (document.getElementById ('Código'). InnerHtml); ... – Justin

+0

podría funcionar, pero eso es casi lo último a lo que me gustaría recurrir. –

-1

De alguna manera parece que su código.El texto se pierde en la traducción en alguna parte, no se conocen detalles, quizás sea por diseño; de todos modos el siguiente hace el trabajo:

protected void PopulatePlaceholder(object sender, EventArgs e) 
    { 
     Button button = new Button(); 
     button.ID = "Push"; 
     button.Text = "push"; 
     button.OnClientClick = "javascript:return false;"; 
//  Code.Text = 
     PlaceMe.Controls.Add(button); 
     PlaceMe.Controls.Add(new LiteralControl("<script type=\"text/javascript\"> function bindEvents() { $('#" + button.ClientID + "').click(function() { alert('hello'); }); } bindEvents(); </script>")); 
    } 

Puesto que ya está construyendo el código JavaScript de código subyacente que también podría agregar el control dinámicamente también.

+0

Este pequeño ejemplo es solo indicativo de mi proceso, el código real es de alrededor de 200 líneas de javascript que hace algunas cosas muy complejas. Necesito mantenerlo, ¡así que no hay realmente una opción de mantener el javascript en el código! –

+0

En su ejemplo, ya está compilando el código. Texto del código subyacente; ¿Estás diciendo que no quieres ejecutar el javascript desde el código? Supuse que reemplazaría la alerta con la llamada a una nueva función, pasando el ID como parámetro o algo así, de todos modos, simplemente tratando de ayudar – riffnl

+0

Entiendo eso, sin embargo, dije que había más que eso en mi publicación original. –

0

Quizás esté interesado para esto: http://api.jquery.com/live/

Casi .bind() compatibles (excepciones enumeradas en el siguiente enlace) - sino que también se une a elementos añadidos/modificados más adelante.

O quizás también pruebe .delegate() - no puede reemplazar directamente llamadas .bind(), pero en la mayoría de los casos es mucho más rápido.

Cuestiones relacionadas