Aplikacja mapy wymaga odświeżenia w celu zainicjowania

9

Próbowałem tego pytania na StackOverflow, ale nie otrzymałem żadnych odpowiedzi. Mam nadzieję, że wszyscy możecie być w stanie pomóc.

Tworzenie aplikacji do mapowania w JavaScript / Dojo:

Kiedy ładuję aplikację w przeglądarce, ładuje elementy HTML, ale potem przestaje przetwarzać. Muszę odświeżyć przeglądarkę, aby załadowała resztę strony i javascript.

Cały dzień testowałem i debugowałem i doszedłem do wniosku, że moje zewnętrzne pliki JS znajdują się w niewłaściwym miejscu (jestem nowicjuszem). Naprawiono to, a aplikacja ładuje się świetnie ... Z WYJĄTKIEM jednego z moich plików nie można odczytać poprawnie lub wcale.

Kiedy domyślnie przenoszę zawartość danego zewnętrznego pliku JS do głównego kodu, funkcje, które zawierają, działają dobrze ... ALE mapa wymaga odświeżenia ponownie.

Stumped Poniżej znajduje się kod w zewnętrznym pliku JS, który powoduje mój problem. Nie mogę zrozumieć, dlaczego jest to problem, ponieważ funkcje działają zgodnie z oczekiwaniami, gdy nie są zewnętrzne.

Każda pomoc jest mile widziana.

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

Oto przednia część mojego kodu

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

EDYCJA 2 Całkowicie przepisałem aplikację, umieszczając cały kod (oprócz css) w głównym pliku default.html. Testowałem kawałek po kawałku, aby upewnić się, że działa tak, jak chcę. Dodanie kodu przełączającego jest jedynym kodem, który go wyrzuca i powoduje dodatkowe odświeżenie.

Na razie używam dijit.TitlePane do przechowywania rozwijanych elementów (galeria map bazowych, warstwy, legenda). Jednak dzięki temu nie można zmienić wyglądu i wyglądu, aby były obrazami, co jest moim ostatecznym celem.

Czy ktoś może zasugerować alternatywę, abym mógł użyć 3 różnych obrazów, aby po kliknięciu obrazu i rozwijanym menu otworzyło się galeria map bazowych, lista warstw i legenda?

Craig
źródło
Nie widzę tu tagu head / body, czy cały kod javascript jest załadowany do nagłówka, czy nie?
Glenn Plas
Przepraszam. Naprawione. Jakoś to sformatowałem, kiedy zacząłem pisać.
Craig
próbowałem, ale nic. Jestem prawie pewien, że problem dotyczy moich funkcji dojo.fx.Toggler. Wszystkie moje inne zewnętrzne pliki js działają idealnie. Nie jestem pewien, dlaczego mam problemy. Skontaktowałem się z ESRI i zastanawiają się nad tym, więc mam nadzieję, że wkrótce otrzymam rozwiązanie.
Craig
Czy próbowałeś użyć narzędzi programistycznych Chrome, aby zobaczyć, które pliki zewnętrzne są ładowane? To może przynajmniej powiedzieć, jak daleko Twoja strona się ładuje i gdzie są błędy.
pecoanddeco

Odpowiedzi:

7

Skonsolidowałbym wszystkie te wywołania dojo.addOnLoad (). Podejrzewam, że coś się nie ładuje przed wywołaniem funkcji.

Usuń wszystkie wywołania dojo.addOnLoad ze wszystkich zewnętrznych plików javascript i połącz je w jedno wywołanie w głównym pliku HTML. Umieść wszystkie funkcje, które chcesz uruchomić podczas ładowania, w nowej funkcji u dołu skryptu javascript:

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

Zapewni to, że wszystko zostało załadowane przed próbą uruchomienia jakichkolwiek funkcji.

Mintx
źródło
5

Jeśli chcesz dokładniej kontrolować / przetestować to głębiej, poza tym, co każdy framework (jquery / dojo) musi to uruchomić. Możesz spróbować tej małej biblioteki:

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

A następnie użyj tego w ten sposób:

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

Zasadniczo mówisz: poczekaj, aż zrobisz coś, aż ten div będzie istniał. Zachowuje się inaczej niż document.ready, „odpalając” nieco później. więc dla ciebie umieściłbyś dojo.*tutaj kod .

To świetny test, aby sprawdzić, czy zdarzy się, że ukąsisz kolejność ładowania jakiegoś kodu javascript. Daję to, ponieważ przydało się (rozwiązywać) rozwiązywać tego rodzaju problemy.

Glenn Plas
źródło
Próbowałem włączyć twoją sugestię do mojego kodu bez powodzenia. Czy możesz mi pomóc wyjaśnić, gdzie to powinno pójść w moim istniejącym bałaganie?
Craig
umieść górny blok w osobnym pliku js, dołącz go do nagłówka, a następnie przetestuj elementy DOM, na których działasz, w kodzie: onAvailable('basemapToggle', function () { dojo.addOnLoad(basemapToggle); });To nie jest bezpośrednie rozwiązanie, ale pomoże ci zrozumieć problem z zamówieniem ładowania
Glenn Plas
3

Wygląda na to, że masz problem ze zleceniem skryptu. Twój plik toggles.js polega na ładowaniu dojo. Jednak w html wywołujesz toggles.js przed załadowaniem interfejsu javascript ESRI, który ładuje dojo. Oto sugestia dotycząca sposobu reorganizacji skryptów.

...
<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
źródło
Próbowałem ponownie zamówić skrypty. Kiedy umieszczam zewnętrzne skrypty po skrypcie API, ładuje się tylko HTML (nagłówek, logo, pod nagłówek). Następnie muszę odświeżyć, aby załadować javascript.
Craig
Zredagowałem moją ostatnią odpowiedź. Spróbuj także umieścić skrypt dojo.requires przed plikami zewnętrznymi. Możesz także rozważyć przeniesienie zewnętrznych skryptów na spód html, aby upewnić się, że wszystkie elementy DOM zostały załadowane przed uruchomieniem tych skryptów.
raykendo
obie edytowane opcje powodują ten sam błąd, który wymaga odświeżenia, aby załadować plik js.
Craig