2012-05-25 8 views
9

En la muestra he juntado, necesito:

  1. , utilizar un post jQuery dentro de $ (document) ready para tomar una "billete" yo uso posterior
  2. en caso de éxito del post, llamar a otra función ("AddTicketAndRender()") y en aquel billete
  3. en AddTicketAndRender(), reemplazar un valor de marcador de posición en una plantilla HTML con el billete que fue pasado. La plantilla HTML define un objeto que necesito representar.
  4. Añadir la plantilla HTML para cuerpo y render:

    function addTicketAndRender(incomingTicket){ 
    
        //For now, just touch the spinner, don't worry about the ticket. 
        var template = $('#tableauTemplate').html(), 
         filledTemplate = template.replace('{placeholder}','yes'); 
    
    
        $('body').append(filledTemplate);} 
    

tengo este trabajo en jsFiddle:

http://jsfiddle.net/vm4bG/4/

Sin embargo, cuando combino el código HTML y JavaScript juntos en un solo archivo htm, la visualización que quiero no se muestra en Chrome, IE o Firefox.

Aquí hay una fuente completa del HTM que no está funcionando. ¿Alguien puede ver algo que obviamente está mal? Mi script de marcado & está por debajo y/o aquí: http://tableau.russellchristopher.org:81/rfc1.htm

<html> 
<head> 
<script type="text/javascript" src="http://public.tableausoftware.com/javascripts/api/viz_v1.js"></script> 
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script> 
</head> 

<!-- template code follows --> 
<script type="text/template" id="tableauTemplate"> 

<div class="tableauPlaceholder" id="tableauPlaceholder" style="width:654px; height:1469px;background-image: url('http://tableau.russellchristopher.org:81/Background.gif'); top: 0px; left: 0px; width: 100%; margin-left: 76px;"> 
    <object class="tableauViz" width="654" height="1469"> 
     <param name="host_url" value="http%3A%2F%2Fpublic.tableausoftware.com%2F"/> 
     <param name="site_root" value="" /> 
     <param name="name" value="AnalyticsIncJavaScript&#47;AnalyticsInc" /> 
     <param name="tabs" value="no" /> 
     <param name="toolbar" value="yes" /> 
     <param name="static_image" value="tableau.russellchristopher.org:81/Background.gif"/> 
     <param name="animate_transition" value="yes" /> 
     <param name="display_static_image" value="yes" /> 
     <param name="display_spinner" value="{placeholder}" id="display_spinner" /> 
     <param name="display_overlay" value="yes" /> 
     <param name="display_count" value="yes" /> 
    </object> 
</div> 
</script> 
<!-- end of template --> 

<body> 
<script> 
function addTicketAndRender(incomingTicket){ 

// grab tableau template code and replace ticket placeholder with incomingTicket from $.post 
console.log("Add and Render"); 

    //For now, just touch the spinner, don't worry about the ticket. 
    var template = $('#tableauTemplate').html(), 
     filledTemplate = template.replace('{placeholder}','no'); 


    $('body').append(filledTemplate); 
    console.log(incomingTicket); 
    console.log("Appended."); 

} 

$(document).ready(function() { 
    console.log("ready"); 
    var trustedURL = "http://tableau.russellchristopher.org/trusted", 
     userName = "foo", 
     serverURL = "http://tableau.russellchristopher.org/"; 


    $.post(trustedURL, { 
     username: userName, 
     server: serverURL, 
     client_ip: "", 
     target_site: "" 
    }, function(response) { 
     addTicketAndRender(response); 
    }); 


}); 

</script> 


</body> 

</html>  

llamadas a CONSOLE.LOG en la función del éxito está registrando información correcta - así que sé que estoy donde necesito - pero el objeto doesn' Parece que hace lo que necesita.

+2

El elemento no quede anexa, debido a que el DOM no está listo. Es por eso que hay un evento "DOM listo". –

+0

Cuidado con jsFiddle. De forma predeterminada, pone su código JavaScript en el evento 'onload', que ocurre ** muy, muy tarde ** en el proceso de carga de la página (mucho después de que" DOM ​​esté listo "). Y, de hecho, su http://jsfiddle.net/vm4bG/2/ fiddle está configurado exactamente de esa manera (e incluye MooTools, ¿deseabas MooTools?). –

+0

Pero si llamo a la función que hace esto desde adentro $ (document) .ready(), ¿no estaría listo, por definición, el DOM? –

Respuesta

5

FYI, su enlace tableau.russellchristopher.org no funciona. No sé cómo tendrías esto trabajando en jsfiddle tampoco; recibo un error de origen cruzado cuando lo intento.

  1. Un problema obvio es que el elemento de script que contiene la plantilla se encuentra en la región inferior entre </head> y <body>. Póngalo dentro de body.

  2. Aquí es lo que creo que podría estar sucediendo: parece que el API de Tableau JavaScript está configurado para procesar los elementos object.tableauViz cuando DOMContentLoaded o load incendios. Está insertando el marcado <object> en el documento en la devolución de llamada para una solicitud asíncrona. Así que estoy pensando que los eventos de carga se están disparando, y la API de Tableau está haciendo su inicialización antes de que su marcado <object> se inserte en el documento.

    Quizás registre sus propios oyentes para esos eventos y llame al console.log() para ver si se ejecutan antes de su devolución de llamada $.post.

    Desafortunadamente, el método createVizesAndStartLoading() que realiza la inicialización (por ejemplo, recuperar object.tableauViz elementos del documento) no parece estar accesible. Parece que es posible que pueda agregar su elemento llamando al window.tableau.createViz(), pero desafortunadamente createVizesAndStartLoading() realiza algún preprocesamiento (por ejemplo, configuración de width/height valores) que debe duplicar o anular.

Recuperar plantilla de forma sincrónica

probar este lugar de su $.post():

$.ajax({ 

    url : trustedURL, 

    data : { 

    username : userName, 

    server : serverURL, 

    client_ip : "", 

    target_site : "" 

    }, 

    async : false 

}).done(addTicketAndRender); 
+0

Lo siento, lo siento, la VM que hospedaba mi servidor web estaba inactiva Y logré golpear el httpd.conf con el encabezado establecido Access-Control-Allow-Origin ... por lo que el POST no iba a funcionar hasta que lo arreglé. Lo cual hice. FYI, intenté # 1, y no vi ningún cambio en el comportamiento, voy a comenzar a trabajar en el # 2. –

+0

.... y ahora lo que solía funcionar en JSFiddle ya no funciona. Al diablo con esto, usaré PHP y .echo el valor del ticket. Soy nuevo en esto pero logré poner un punto de interrupción en CreateVizesAndStartLoading(), y se está ejecutando antes de que el objeto esté allí. Ve 0 "nodos de parámetros" como resultado, y esos son los retoños que le dicen a la visualización cómo comportarse. –

+0

Sí, estaba pensando en usar PHP o quizás haciendo una solicitud sincrónica a través de jQuery para obtener el marcado de la plantilla. Si no puede incluir el archivo localmente a través de PHP, probablemente pueda incluirlo a través de HTTP. – JMM

4

Es difícil saber a partir de la gran cantidad de código presentado exactamente lo que se está ejecutando en, por lo que el principio general:

Con el fin de encontrar y operar en un elemento DOM, debe existir el elemento. Así, por ejemplo, este código fallará:

<script>$("#target").html("Updated");</script> 
<p id="target">Not updated</p> 

Live example | source

El objetivo no se actualizará. Este código funcionará:

<p id="target">Not updated</p> 
<script>$("#target").html("Updated");</script> 

Live example | source

La única diferencia es que la etiqueta script está detrás del objetivo, por lo que sabe que el objetivo existe en el DOM cuando intenta operarlo. (Esta es fiable; ver what Google's dev team have to say about it, y el YUI guidelines.)

Bibliotecas tradicionalmente incluyen eventos "DOM" listas porque la incorporada en uno, el evento load del objeto window, no se dispara hasta muy, muy tarde en el proceso (una vez todas las referencias externas se han cargado, incluidas todas las imágenes). Pero la gente quería hacer las cosas antes, incluso cuando las imágenes aún se estaban cargando. Los eventos de estilo "listo" permiten que el código de script se pueda colocar en cualquier parte del marcado (a la gente le gusta ponerlo en head, por alguna razón), pero si usa el evento "listo", sabe que en realidad no se llamará hasta todo el marcado ha sido procesado.

lo tanto, el resultado es: o bien utilizar el evento ready, o (mejor) mover el código que se basa en elementos de después de esos elementos en el marcado (por lo general mejor justo antes de la etiqueta de cierre </body>).

+0

Gracias. También simplifiqué el código en jsfiddler. –

+0

He estado probando fuera de jsbin y jsfiddler, el mismo resultado. También moví mi lógica .ready() y la función de éxito $ .post justo antes de la etiqueta de cierre (ver arriba en el bloque "fuente que no funciona"). ¿Podría ser que cuando añado ese bloque de HTML que incluye mi definición (después de que el DOM esté listo) que el DOM necesita "actualizarse" y durante ese "período de actualización" es cuando el resto de mi código intenta trabajar con el que aún no se ha "inicializado"? Después de un .append, ¿hay alguna manera de suspender la operación de la página hasta que el DOM esté nuevamente listo? –

+0

@RussellChristopher: Puede manipular elementos DOM tan pronto como se agreguen.Tendrá que armar un ejemplo ** mucho más pequeño ** (sin incluir guiones y hojas de estilo de muchos otros lugares, y asegúrese de desactivar las cosas en las que se enciende jsFiddle; sus ejemplos aún incluyen MooTools , como señalé anteriormente, y usando el evento 'onload'). –

Cuestiones relacionadas