แอปพลิเคชันแผนที่ต้องรีเฟรชเพื่อเริ่มต้น


9

ฉันลองคำถามนี้ใน StackOverflow แต่ไม่ได้รับคำตอบใด ๆ หวังว่าคุณทุกคนจะสามารถช่วยได้

การสร้างแอปพลิเคชันการจับคู่เว็บใน Javascript / Dojo:

เมื่อฉันโหลดแอพในเบราว์เซอร์มันจะโหลดองค์ประกอบ html แต่ก็หยุดการประมวลผล ฉันต้องรีเฟรชเบราว์เซอร์เพื่อให้โหลดส่วนที่เหลือของหน้าและจาวาสคริปต์

ฉันทำการทดสอบและแก้ไขจุดบกพร่องตลอดทั้งวันและคิดว่าฉันมีไฟล์ JS ภายนอกของฉันในจุดที่ผิด (ฉันเป็นมือใหม่) แก้ไขว่าและแอปโหลดได้ดีมาก ... ยกเว้นไฟล์ใดไฟล์หนึ่งของฉันที่ไม่สามารถอ่านได้อย่างถูกต้องหรือเลย

เมื่อฉันย้ายเนื้อหาของไฟล์ JS ภายนอกที่สงสัยไปยังรหัสหลักในค่าเริ่มต้นฟังก์ชันการทำงานที่พวกเขามีทำงานได้ดี ... แต่แผนที่ต้องการการรีเฟรชอีกครั้ง

นิ่งงัน ด้านล่างเป็นรหัสในไฟล์ JS ภายนอกที่ทำให้เกิดปัญหาของฉัน ฉันไม่สามารถเข้าใจได้ว่าทำไมมันถึงมีปัญหาเพราะฟังก์ชั่นทำงานได้อย่างที่คาดไว้เมื่อมันไม่ใช่ภายนอก

ความช่วยเหลือใด ๆ ที่ชื่นชมอย่างมาก

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

นี่คือส่วนหน้าของรหัสของฉัน

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

แก้ไข 2 ฉันเขียนแอปใหม่อย่างสมบูรณ์โดยวางรหัสทั้งหมด (ยกเว้น css) ในไฟล์ default.html หลัก ฉันทดสอบทีละชิ้นเพื่อให้แน่ใจว่ามันทำงานตามที่ฉันต้องการ การเพิ่มรหัส toggles เป็นรหัสเดียวที่ส่งมาและทำให้เกิดการรีเฟรชพิเศษ

ดังนั้นสำหรับตอนนี้ฉันกำลังใช้ dijit.TitlePane เพื่อเก็บองค์ประกอบแบบหล่นลง (แกลเลอรี่ basemap, เลเยอร์, ​​ตำนาน) อย่างไรก็ตามด้วยสิ่งนี้คุณไม่สามารถเปลี่ยนรูปลักษณ์และความรู้สึกเพื่อสร้างภาพซึ่งเป็นเป้าหมายสุดท้ายของฉัน

ใครสามารถแนะนำทางเลือกอื่นเพื่อให้ฉันสามารถใช้ 3 ภาพที่แตกต่างกันดังนั้นเมื่อคุณคลิกที่ภาพและเมนูแบบหล่นลงจะเปิดขึ้นถือแกลเลอรี่แผนที่, รายการเลเยอร์และตำนาน?


ฉันไม่เห็นแท็ก head / body ในที่นี้รหัส javascript ทั้งหมดของคุณโหลดในส่วนหัวหรือไม่?
Glenn Plas

ขอโทษ ซ่อมมัน. อย่างใดมันก็จัดรูปแบบออกเมื่อฉันเริ่มโพสต์
Craig


ลองแล้ว แต่ไม่มีอะไร ฉันเกือบจะแน่ใจว่าปัญหาเกิดขึ้นกับฟังก์ชั่น dojo.fx.Toggler ของฉัน ไฟล์ js ภายนอกอื่น ๆ ของฉันทำงานได้อย่างสมบูรณ์ ไม่แน่ใจว่าทำไมฉันถึงมีปัญหา ได้รับการติดต่อกับ ESRI และพวกเขากำลังมองหามันดังนั้นหวังว่าฉันจะได้รับการแก้ไขในไม่ช้า
Craig

คุณได้ลองใช้บางอย่างเช่นเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Chrome เพื่อดูว่าไฟล์ภายนอกกำลังโหลดจริงหรือไม่ อย่างน้อยก็อาจบอกคุณได้ว่าหน้าเว็บของคุณโหลดได้มากแค่ไหนและเกิดข้อผิดพลาดใด ๆ
pecoanddeco

คำตอบ:


7

ฉันจะรวมการเรียก dojo.addOnLoad () ทั้งหมด ฉันสงสัยว่าบางอย่างไม่ได้รับการโหลดก่อนที่จะเรียกใช้ฟังก์ชัน

ตัดการเรียก dojo.addOnLoad ทั้งหมดจากไฟล์จาวาสคริปต์ภายนอกทั้งหมดของคุณและรวมเข้าเป็นหนึ่งการโทรในไฟล์ HTML หลักของคุณ ใส่ฟังก์ชั่นทั้งหมดที่คุณต้องการโหลดลงในฟังก์ชั่นใหม่ที่ด้านล่างของจาวาสคริปต์ของคุณดังนี้:

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

สิ่งนี้จะช่วยให้มั่นใจว่าทุกอย่างได้โหลดก่อนที่จะพยายามปิดฟังก์ชั่นใด ๆ


5

หากคุณต้องการ finecontrol / ทดสอบสิ่งนี้ให้ลึกกว่านั้นสิ่งใดที่กรอบงาน (jquery / dojo) ต้องเริ่มต้นสิ่งนี้ คุณสามารถลองใช้ห้องสมุดเล็ก ๆ นี้:

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

แล้วใช้มันเช่นนี้

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

โดยพื้นฐานแล้วสิ่งที่คุณพูดคือ: รอจนกว่าจะทำอะไรจนกว่า div นี้จะมีอยู่ มันทำงานแตกต่างจาก document.ready แล้ว 'firing' a tad ภายหลัง ดังนั้นสำหรับคุณคุณจะต้องใส่รหัสด้วยdojo.*ที่นี่

เป็นการทดสอบที่ยอดเยี่ยมเพื่อดูว่าคุณถูกกัดโดยลำดับการโหลดของรหัสจาวาสคริปต์หรือไม่ ฉันให้สิ่งนี้เพราะมันใช้ในการแก้ไขปัญหาเหล่านี้ได้ดี


ฉันได้ลองรวมคำแนะนำของคุณเข้ากับโค้ดของฉันโดยไม่มีโชค คุณสามารถช่วยอธิบายเพิ่มเติมได้ว่าควรจะไปที่ใดในระเบียบที่มีอยู่ของฉัน?
เครก

ใส่บล็อกยอดนิยมในไฟล์ js แยกรวมไว้ในส่วนหัวแล้วทดสอบองค์ประกอบ dom ของคุณที่คุณทำในรหัสของคุณ: onAvailable('basemapToggle', function () { dojo.addOnLoad(basemapToggle); });มันไม่ใช่วิธีการแก้ปัญหาโดยตรง แต่จะช่วยให้คุณเข้าใจปัญหาการสั่งซื้อโหลดของคุณ
Glenn Plas

3

ดูเหมือนว่าคุณกำลังมีปัญหาการสั่งซื้อสคริปต์ toggles.js ของคุณขึ้นอยู่กับการโหลด dojo อย่างไรก็ตามใน html ของคุณคุณกำลังเรียก toggles.js ก่อนที่จะโหลด javascript api ของ ESRI ซึ่งโหลด dojo นี่คือคำแนะนำเกี่ยวกับวิธีการจัดระเบียบสคริปต์ของคุณใหม่

...
<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>
    ...

ฉันพยายามสั่งสคริปต์อีกครั้ง เมื่อฉันวางสคริปต์ภายนอกหลังจากสคริปต์ API เฉพาะโหลด html เท่านั้น (ส่วนหัว, โลโก้, ส่วนหัวย่อย) ฉันต้องรีเฟรชเพื่อรับจาวาสคริปต์เพื่อโหลด
Craig

ฉันแก้ไขคำตอบสุดท้ายของฉัน ลองวางสคริปต์ dojo.requires ข้างหน้าไฟล์ภายนอกของคุณ นอกจากนี้คุณอาจพิจารณาย้ายสคริปต์ภายนอกไปยังด้านล่างของเนื้อหา html เพื่อให้แน่ใจว่าองค์ประกอบ DOM ทั้งหมดโหลดไว้ก่อนที่สคริปต์เหล่านั้นจะทำงาน
raykendo

ทั้งสองตัวเลือกการแก้ไขของคุณส่งผลให้เกิดข้อผิดพลาดเดียวกันต้องรีเฟรชเพื่อโหลด js
Craig
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.