La aplicación de mapas requiere actualizar para inicializar

9

Intenté esta pregunta en StackOverflow pero no obtuve ninguna respuesta. Esperando que todos puedan ayudar.

Crear una aplicación de mapeo web en Javascript / Dojo:

Cuando cargo la aplicación en un navegador, carga los elementos html pero luego detiene el procesamiento. Tengo que actualizar el navegador para que cargue el resto de la página y el javascript.

He hecho pruebas y depuración todo el día y descubrí que tenía mis archivos JS externos en el lugar equivocado (soy un novato). Se corrigió eso y la aplicación se carga muy bien ... EXCEPTO que uno de mis archivos no se lee correctamente, o no se lee.

Cuando muevo el contenido del archivo JS externo en cuestión al código principal predeterminado, la funcionalidad que contienen funciona bien ... PERO el mapa requiere la actualización nuevamente.

Perplejo. A continuación se muestra el código en el archivo JS externo que está causando mi problema. No puedo entender por qué es un problema porque las funciones funcionan como se esperaba cuando no es externo.

Cualquier ayuda es muy apreciada.

//Toggles
function basemapToggle() {
            basemaptoggler = new dojo.fx.Toggler({
                node: "basemaptoggle",
                showFunc : dojo.fx.wipeIn,
                showDuration: 1000,
                hideDuration: 1000,
                hideFunc : dojo.fx.wipeOut
            })
        }
        dojo.addOnLoad(basemapToggle);

        function layerToggle() {
            layertoggler = new dojo.fx.Toggler({
                node: "layertoggle",
                showFunc : dojo.fx.wipeIn,
                showDuration: 750,
                hideDuration: 750,
                hideFunc : dojo.fx.wipeOut
            })
        }
        dojo.addOnLoad(layerToggle);

        function legendToggle() {
            legendtoggler = new dojo.fx.Toggler({
                node: "legendtoggle",
                showFunc : dojo.fx.wipeIn,
                hideFunc : dojo.fx.wipeOut
            })
        }
        dojo.addOnLoad(legendToggle);

Aquí está la parte delantera de mi código

<!DOCTYPE HTML> 
  <html>  
  <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=8, IE=9" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title> 
        Zoning Classifications
    </title> 
        <link rel="Stylesheet" href="ZoningClassifications.css" />
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/claro/claro.css">
        <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/esri/dijit/css/Popup.css">
        <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dojox/grid/resources/Grid.css">
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dojox/grid/resources/claroGrid.css">
    <style type="text/css"> 
    </style> 

        <script src="JS/layers.js"></script>
        <script src="JS/search.js"></script>
        <script src="JS/basemapgallery.js"></script>

        <script src="JS/identify.js"></script>
        <script src="JS/toggles.js"></script>
        <script type="text/javascript"> 
      var djConfig = {
        parseOnLoad: true
      };
    </script> 
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.0"></script>
    <script type="text/javascript"> 

            dojo.require("dijit.dijit"); // optimize: load dijit layer
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("esri.map");
      dojo.require("dijit.TitlePane");
      dojo.require("esri.dijit.BasemapGallery");
      dojo.require("esri.arcgis.utils");
            dojo.require("esri.tasks.locator");
            dojo.require("esri.dijit.Legend");
            dojo.require("esri.dijit.Popup");
            dojo.require("dijit.form.Button");
            dojo.require("dojo.fx");
            dojo.require("dijit.Dialog");
            dojo.require("dojo.ready");
      dojo.require("dijit.TooltipDialog");
            dojo.require("dojox.grid.DataGrid");
      dojo.require("dojo.data.ItemFileReadStore");
      dojo.require("esri.tasks.find");

EDITAR 2 He reescrito completamente la aplicación colocando todo el código (excepto el css) en el archivo principal default.html. Probé pieza por pieza para asegurarme de que funcionara como quiero. Agregar el código de alternancia es el único código que lo arroja y causa la actualización adicional.

Así que por ahora estoy usando dijit.TitlePane para mantener los elementos desplegables (galería de mapas base, capas, leyenda). Sin embargo, con esto no puede cambiar la apariencia para hacerlas imágenes, que es mi objetivo final.

¿Alguien puede sugerir una alternativa para que pueda usar 3 imágenes diferentes para que cuando haga clic en la imagen y se abra el menú desplegable que contiene la galería del mapa base, la lista de capas y la leyenda?

Craig
fuente
No veo una etiqueta de cabeza / cuerpo aquí, ¿está todo su código JavaScript cargado en el encabezado o no?
Glenn Plas
Lo siento. Arreglado. De alguna manera se formateó cuando comencé la publicación.
Craig
Lo intenté, pero nada. Estoy casi seguro de que el problema es con mis funciones dojo.fx.Toggler. Todos mis otros archivos js externos funcionan perfectamente. No estoy seguro de por qué tengo problemas. Se contactó con ESRI y lo están investigando, así que espero tener una resolución pronto.
Craig
¿Has intentado usar algo como las herramientas de desarrollador de Chrome para ver qué archivos externos realmente se están cargando? Esto al menos podría decirle qué tan lejos está llegando su página al cargar los archivos y dónde están los errores.
pecoanddeco

Respuestas:

7

Yo consolidaría todas esas llamadas dojo.addOnLoad (). Sospecho que algo no se está cargando antes de que se llame a una función.

Elimine todas las llamadas dojo.addOnLoad de todos sus archivos javascript externos y agrúpelos en una sola llamada en su archivo HTML principal. Ponga todas las funciones que desea activar en la carga en una nueva función en la parte inferior de su javascript como esta:

function init() {
  basemapToggle();
  layerToggle();
  whatEver();
}
dojo.addOnLoad(init);

Esto asegurará que todo se haya cargado antes de intentar activar cualquier función.

Menta
fuente
5

Si desea controlar / probar con mayor profundidad, fuera de lo que cualquier marco (jquery / dojo) tiene que iniciar esto. Puedes probar esta pequeña biblioteca:

var stack = [],
    interval,
    loaded; // has window.onload fired?

function doPoll() {
  var notFound = [];
  for (var i=0; i<stack.length; i++) {
    if (document.getElementById(stack[i].id)) {
      stack[i].callback();
    } else {
      notFound.push(stack[i]);
    }
  }
  stack = notFound;
  if (notFound.length < 1 || loaded) {
    stopPolling();
  }
}

function startPolling() {
  if (interval) {return;}
  interval = setInterval(doPoll, 10);
}

function stopPolling() {
  if (!interval) {return;}
  clearInterval(interval);
  interval = null;
}

function onAvailable(id, callback) {
  stack.push({id:id, callback:callback});
  startPolling();
}

window.onload = function() {
  loaded = true;
  doPoll();
};

Y luego úsalo así:

onAvailable('map', function () {
    // Only do stuff here once the map div is available (this always happens after the DOM is ready)
  ....
});

Básicamente lo que haces es decir: espera para hacer cosas hasta que exista este div. Se comporta de manera diferente a document.ready, 'disparando' un poco más tarde. así que para ti, pondrías el código dojo.*aquí.

Es una gran prueba para ver si te muerde el orden de carga de algún código JavaScript. Estoy dando esto porque ha sido de gran utilidad (solucionar) resolver este tipo de problemas.

Glenn Plas
fuente
Intenté incorporar su sugerencia a mi código sin suerte. ¿Pueden ayudarme a explicar a dónde debería ir esto en mi desorden existente?
Craig el
coloque el bloque superior en un archivo js separado, inclúyalo en el encabezado, luego pruebe los elementos dom en los que actúa, en su código: onAvailable('basemapToggle', function () { dojo.addOnLoad(basemapToggle); });no es una solución directa, pero lo ayudará a comprender su problema de orden de carga
Glenn Plas
3

Parece que tienes un problema con el orden del script. Su toggles.js se basa en la carga del dojo. Sin embargo, en su html, está llamando a toggles.js antes de cargar la API de JavaScript de ESRI, que carga dojo. Aquí hay una sugerencia sobre cómo podría reorganizar sus scripts.

...
<style type="text/css"></style> 

    <script type="text/javascript"> 
       var djConfig = { parseOnLoad: true };
    </script> 
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.0"></script>
    <script type="text/javascript"> 

        dojo.require("dijit.dijit"); // optimize: load dijit layer
        dojo.require("dijit.layout.BorderContainer");
        dojo.require("dijit.layout.ContentPane");
        dojo.require("esri.map");
        dojo.require("dijit.TitlePane");
        dojo.require("esri.dijit.BasemapGallery");
        dojo.require("esri.arcgis.utils");
        dojo.require("esri.tasks.locator");
        dojo.require("esri.dijit.Legend");
        dojo.require("esri.dijit.Popup");
        dojo.require("dijit.form.Button");
        dojo.require("dojo.fx");
        dojo.require("dijit.Dialog");
        dojo.require("dojo.ready");
        dojo.require("dijit.TooltipDialog");
        dojo.require("dojox.grid.DataGrid");
        dojo.require("dojo.data.ItemFileReadStore");
        dojo.require("esri.tasks.find");
    </script>
    <script src="JS/layers.js"></script>
    <script src="JS/search.js"></script>
    <script src="JS/basemapgallery.js"></script>

    <script src="JS/identify.js"></script>
    <script src="JS/toggles.js"></script>
    ...
raykendo
fuente
Intenté volver a ordenar los guiones. Cuando coloco los scripts externos después del script API, solo se carga el html (encabezado, logotipo, subtítulo). Luego tengo que actualizar para cargar el javascript.
Craig
Edité mi última respuesta. Intente también colocar el script dojo.requires antes que sus archivos externos. Además, puede considerar mover sus scripts externos a la parte inferior del cuerpo html, para asegurarse de que todos los elementos DOM se hayan cargado antes de que se ejecuten esos scripts.
raykendo
ambas opciones editadas dan como resultado el mismo error, que necesita actualizar para cargar el js.
Craig