L'application de carte nécessite un rafraîchissement pour initialiser

9

J'ai essayé cette question sur StackOverflow mais je n'ai obtenu aucune réponse. En espérant que vous puissiez tous aider.

Création d'une application de cartographie Web en Javascript / Dojo:

Lorsque je charge l'application dans un navigateur, elle charge les éléments html mais arrête ensuite le traitement. Je dois rafraîchir le navigateur pour qu'il charge le reste de la page et le javascript.

J'ai fait des tests et du débogage toute la journée et j'ai compris que j'avais mes fichiers JS externes au mauvais endroit (je suis une recrue). Correction de cela et l'application se charge très bien ... SAUF l'un de mes fichiers n'est pas lu correctement, ou pas du tout.

Lorsque je déplace le contenu du fichier JS externe en question vers le code principal par défaut, les fonctionnalités qu'ils contiennent fonctionnent correctement ... MAIS la carte nécessite à nouveau d'être actualisée.

Perplexe. Vous trouverez ci-dessous le code du fichier JS externe à l'origine de mon problème. Je ne peux pas comprendre pourquoi c'est un problème parce que les fonctions fonctionnent comme prévu quand ce n'est pas externe.

Toute aide est grandement appréciée.

//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);

Voici la partie avant de mon code

<!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");

EDIT 2 J'ai complètement réécrit l'application en plaçant tout le code (sauf le CSS) dans le fichier default.html principal. J'ai testé pièce par pièce pour m'assurer qu'il fonctionnait comme je le voulais. L'ajout du code bascule est le seul code qui le lance et provoque l'actualisation supplémentaire.

Donc, pour l'instant, j'utilise dijit.TitlePane pour contenir les éléments déroulants (galerie de fond de carte, couches, légende). Cependant, avec cela, vous ne pouvez pas changer l'apparence pour en faire des images, ce qui est mon objectif final.

Quelqu'un peut-il suggérer une alternative pour que je puisse utiliser 3 images différentes afin que lorsque vous cliquez sur l'image et que le menu déroulant s'ouvre, contenant la galerie de fond de carte, la liste des couches et la légende?

Craig
la source
Je ne vois pas de balise head / body ici, est-ce que tout votre code javascript est chargé dans l'en-tête ou non?
Glenn Plas
Désolé. A corrigé. D'une manière ou d'une autre, il a été formaté lorsque j'ai commencé le post.
Craig
essayé, mais rien. Je suis presque certain que le problème vient de mes fonctions dojo.fx.Toggler. Tous mes autres fichiers js externes fonctionnent parfaitement. Je ne sais pas pourquoi j'ai des problèmes. Contacté ESRI et ils étudient la question, alors j'espère que j'aurai bientôt une résolution.
Craig
Avez-vous essayé d'utiliser quelque chose comme les outils de développement Chrome pour voir quels fichiers externes sont réellement chargés? Cela pourrait au moins vous dire dans quelle mesure votre page parvient à charger les fichiers et où se trouvent les erreurs.
pecoanddeco

Réponses:

7

Je consoliderais tous ces appels dojo.addOnLoad (). Je soupçonne que quelque chose n'est pas chargé avant qu'une fonction ne soit appelée.

Supprimez tous les appels dojo.addOnLoad de tous vos fichiers javascript externes et regroupez-les en un seul appel dans votre fichier HTML principal. Mettez toutes les fonctions que vous souhaitez lancer en charge dans une nouvelle fonction au bas de votre javascript comme ceci:

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

Cela garantira que tout a été chargé avant d'essayer de déclencher des fonctions.

Mintx
la source
5

Si vous voulez contrôler plus finement / tester cela plus en profondeur, en dehors de tout framework (jquery / dojo) pour démarrer cela. Vous pouvez essayer cette petite bibliothèque:

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();
};

Et puis utilisez-le comme ceci:

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

Fondamentalement, ce que vous faites est de dire: attendez de faire des choses jusqu'à ce que cette div existe. Il se comporte différemment de document.ready, «tirant» un peu plus tard. donc pour vous, vous mettriez le code dojo.*ici.

C'est un excellent test pour voir si vous êtes mordu par l'ordre de chargement d'un code javascript. Je donne ceci parce qu'il a été d'une bonne utilité pour (dépanner) trier ce genre de problèmes.

Glenn Plas
la source
J'ai essayé d'intégrer votre suggestion à mon code sans aucune chance. Pouvez-vous nous expliquer plus en détail où cela devrait aller dans mon désordre actuel?
Craig
mettez le bloc supérieur dans un fichier js séparé, incluez-le dans l'en-tête, puis testez vos éléments dom sur lesquels vous agissez, dans votre code: onAvailable('basemapToggle', function () { dojo.addOnLoad(basemapToggle); });ce n'est pas une solution directement mais cela vous aidera à comprendre votre problème d'ordre de chargement
Glenn Plas
3

Il semble que vous rencontriez un problème d'ordre de script. Votre toggles.js repose sur le chargement du dojo. Cependant, dans votre html, vous appelez toggles.js avant de charger l'api javascript d'ESRI, qui charge le dojo. Voici une suggestion sur la façon de réorganiser vos 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
la source
J'ai essayé de réordonner les scripts. Lorsque je place les scripts externes après le script API, seuls les chargements html (en-tête, logo, sous-en-tête). Je dois ensuite rafraîchir pour charger le javascript.
Craig
J'ai modifié ma dernière réponse. Essayez également de placer le script dojo.requires avant vos fichiers externes. Vous pouvez également envisager de déplacer vos scripts externes au bas du corps html, pour vous assurer que tous les éléments DOM ont été chargés avant l'exécution de ces scripts.
raykendo
vos deux options modifiées entraînent la même erreur, nécessitant un rafraîchissement pour charger le js.
Craig