Aplicativo de mapa requer atualização para inicializar


9

Tentei esta pergunta no StackOverflow, mas não obtive nenhuma resposta. Esperando que todos vocês possam ajudar.

Criando um aplicativo de mapeamento da web em Javascript / Dojo:

Quando carrego o aplicativo em um navegador, ele carrega os elementos html, mas depois interrompe o processamento. Eu tenho que atualizar o navegador para que ele carregue o restante da página e o javascript.

Eu testei e depurei o dia todo e descobri que meus arquivos JS externos estavam no local errado (eu sou um novato). Corrigido isso e o aplicativo carrega muito bem ... EXCETO um dos meus arquivos não está sendo lido corretamente ou não.

Quando movo o conteúdo do arquivo JS externo em questão para o código principal no padrão, a funcionalidade que eles contêm funciona bem ... MAS o mapa requer a atualização novamente.

Perplexo. Abaixo está o código no arquivo JS externo que está causando o meu problema. Não consigo descobrir por que é um problema porque as funções funcionam como esperado quando não são externas.

Qualquer ajuda é muito 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);

Aqui está a parte da frente do meu 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");

EDIT 2 Reescrevi completamente o aplicativo, colocando todo o código (exceto o css) no arquivo default.html principal. Testei peça por peça para garantir que funcionasse como eu queria. Adicionar o código de alternância é o único código que o lança e causa a atualização extra.

Portanto, por enquanto estou usando dijit.TitlePane para manter os elementos suspensos (galeria de mapas base, camadas, legenda). No entanto, com isso, você não pode alterar a aparência e criar imagens, que é o meu objetivo final.

Alguém pode sugerir uma alternativa para que eu possa usar 3 imagens diferentes para que, quando você clicar na imagem e no menu suspenso, abrir a galeria de mapas base, a lista de camadas e a legenda?


Não vejo uma tag de cabeça / corpo aqui, todo o seu código javascript está carregado no cabeçalho ou não?
Glenn Plas

Desculpa. Corrigido. De alguma forma, ele foi formatado quando eu comecei a postagem.
Craig


tentei, mas nada. Estou quase certo de que o problema está nas minhas funções dojo.fx.Toggler. Todos os meus outros arquivos js externos funcionam perfeitamente. Não sei por que estou tendo problemas. Entrei em contato com a ESRI e eles estão analisando, por isso espero ter uma resolução em breve.
Craig

Você já tentou usar algo como as ferramentas de desenvolvedor do Chrome para ver quais arquivos externos estão realmente sendo carregados? Isso pode, pelo menos, dizer a que distância sua página está sendo carregada e onde estão os erros.
Pecoanddeco 24/10/12

Respostas:


7

Eu consolidaria todas essas chamadas dojo.addOnLoad (). Eu suspeito que algo não está sendo carregado antes que uma função seja chamada.

Retire todas as chamadas dojo.addOnLoad de todos os seus arquivos javascript externos e agrupe-as em uma única chamada no seu arquivo HTML principal. Coloque todas as funções que você deseja disparar em uma nova função na parte inferior do seu javascript da seguinte maneira:

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

Isso garantirá que tudo foi carregado antes de tentar disparar qualquer função.


5

Se você deseja controlar / testar isso mais profundamente, fora do que qualquer estrutura (jquery / dojo) precisa para iniciar isso. Você pode tentar esta pequena 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();
};

E então use-o assim:

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

Basicamente, o que você faz é dizer: espere para fazer as coisas até que essa div exista. Ele se comporta de maneira diferente do que document.ready, 'disparando' um pouco mais tarde. então para você, você colocaria o código dojo.*aqui.

É um ótimo teste para ver se você foi mordido pela ordem de carregamento de algum código javascript. Estou dando isso porque foi de bom uso (solucionar problemas) resolver esses tipos de problemas.


Tentei incorporar sua sugestão ao meu código sem sorte. Você pode ajudar a explicar melhor onde isso deve ir na minha bagunça existente?
Craig

coloque o bloco superior em um arquivo js separado, inclua-o no cabeçalho e teste os elementos dom nos quais você atua, no seu código: onAvailable('basemapToggle', function () { dojo.addOnLoad(basemapToggle); });Não é uma solução diretamente, mas ajudará você a entender seu problema de ordem de carga
Glenn Plas,

3

Parece que você está tendo um problema de pedido de script. Seu toggles.js depende do carregamento do dojo. No entanto, em seu html, você está chamando toggles.js antes de carregar a API javascript da ESRI, que carrega dojo. Aqui está uma sugestão de como você pode reorganizar seus 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>
    ...

Eu tentei reordenar os scripts. Quando coloco os scripts externos após o script da API, apenas o html é carregado (cabeçalho, logotipo, subtítulo). Preciso atualizar para obter o javascript para carregar.
22412 Craig

Eu editei minha última resposta. Tente também colocar o script dojo.requires à frente dos arquivos externos. Além disso, você pode considerar mover seus scripts externos para a parte inferior do corpo html, para garantir que todos os elementos DOM tenham sido carregados antes da execução desses scripts.
Raykendo 22/10/12

as duas opções editadas resultam no mesmo erro, sendo necessário atualizar para carregar o js.
22412 Craig
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.