jQuery: manejo de la respuesta mixta html/js ajax

Tiene problemas para acceder al código javascript en una respuesta mixta html/js ajax. jQuery ajax doc estados:

Si se especifica html, cualquier JavaScript incrustado dentro de los datos recuperados se ejecuta antes de que el HTML se devuelva como una cadena.

Lo cual puedo confirmar agregando un fragmento simple a la respuesta html:

<script type="text/javascript"> alert($(this)); </script>

Entonces, ¿cómo retener el acceso al código js frente a la ejecución única? Intentando implementar un inicio de sesión modal (para evitar la pérdida de datos en el tiempo de espera de la sesión en las pantallas de envío de formularios). Por supuesto, necesito poder acceder al código ajax'd js para luego validar los campos de correo electrónico/contraseña y ajax autenticar las credenciales de usuario en el servidor remoto.

Aquí está el fragmento de coffeescript de inicio de sesión modal:

# submit form
$.ajax
  success: (data) -> ...
  error: (data) ->
    popAuth(data.responseText) if(data.status == 401)

popAuth = (title) -> 
  $.fancybox({
    href: "/login"
    ajax: { type: "GET" }
    title: title
  })

¿Quizás pueda agregar una devolución de llamada exitosa a las opciones popAuth() ajax para almacenar el código js devuelto? ¿Qué tal el controlador jQuery "live"? Lamentablemente, este escenario no es tan sencillo como cabría esperar ;-) He visto $.getScript como una opción, pero preferiría no separar html de js ya que el lado del servidor ya ensambla html + js y la llamada ajax original lo elimina todo de una sola vez. (es decir, evite crear un controlador del lado del servidor dedicado para devolver el paquete de contenido del archivo js)

Por supuesto, estoy abierto a soluciones alternativas para solucionar este problema. Por ejemplo, podría almacenar los campos de inicio de sesión y el código de validación de inicio de sesión js en cada pantalla (la aplicación JVM CRUD vive detrás de la interfaz de WordPress, por lo que básicamente se requiere autenticación en cada pantalla) en un div oculto, y luego abrir la ventana de inicio de sesión modal "localmente", que Supongo que evitaría la molesta ejecución js de contenido ajax remoto.

De todos modos, ideas apreciadas! el lado del cliente es a la vez maravillosamente simple y... terriblemente complejo ;-)

preguntado el 12 de junio de 12 a las 11:06

1 Respuestas

Ok, defendiéndome de la verdadera avalancha de respuestas, tomaré una puñalada yo mismo.

Tal como lo entiendo ahora, dado que el contenido mixto de html/js se ejecuta de una sola vez, tenemos una oportunidad de capturar el código js de respuesta ajax y vincularlo al alcance actual.

En primer lugar, en la llamada ajax original (es decir, el envío del formulario que devuelve un posible estado 401 no autorizado) establezca el contexto de la configuración ajax del inicio de sesión modal en $(esto), el ámbito de ejecución actual que contiene la validación de jquery y otro código js compartido necesario para inicio de sesión modal ajax enviar al trabajo.

En mi caso, usando fancybox, agregando un parámetro de contexto, ahora se ve así:

popAuth = (title) -> 
  $.fancybox({
    href: "/login"
    ajax: { type: "GET" }
    context: $(@)
    title: title
  })

Luego, dado que la ventana principal contiene la mayoría de los javascript necesarios, el único requisito es crear un archivo js que vincule el evento de clic del botón del formulario de inicio de sesión modal con la validación y el envío de $.ajax.

# login.coffee
jQuery ->
  $('#loginSubmit').click (e) ->
    e.preventDefault()
    isValid = $('#loginForm').validate().form()
    if isValid
      $('#spinner').show()
      $.ajax
        data: $('#loginForm').serialize()
        success: (data) ->
          $('#status').fadeOut()
          location.href = '/foo'
        error: (data) ->
          $('#status > div').html( data.responseText )
          $('#status').fadeIn()
        complete: () ->
          $('#spinner').hide()

Listo, todo bien, funciona ;-)

Respondido el 12 de junio de 12 a las 13:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.