Uncaught TypeError: Cannot read property 'on&#

2019-05-20 23:54发布

i am trying to display navigation tool and switch base map.Individually both are working good when i combine it its showing Uncaught Type Error: Cannot read property 'on' of undefined.can any tell me what is the mistake

   <!DOCTYPE html>
    <html>  
    <head> 
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

      <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
      <title></title>

      <link rel="stylesheet" href="https://js.arcgis.com/3.15/dijit/themes/claro/claro.css">    
      <link rel="stylesheet" href="https://js.arcgis.com/3.15/esri/css/esri.css">
      <style> 
        html, body, #map { height: 100%; width: 100%; margin: 0; padding: 0; }
        #switch{
        position:absolute;
        right:20px; 
        top:10px; 
        z-Index:999;
        }
        #basemapGallery{
        width:380px;
        height:280px; 
        }
         #HomeButton {
          position: absolute;
          top: 95px;
          left: 20px;
          z-index: 50;
        }
         #navToolbar{
             display: block;
             position: absolute;
             z-index: 2;
             top: 10px;
            left:2px
          }
          .zoominIcon {
           display: block;
            position: absolute;
            width: 16px;
            height: 16px;
          }

          .zoomoutIcon {
            position: absolute;
            width: 16px;
            height: 16px;
          }

          .zoomfullextIcon {
            position: absolute;
            width: 16px;
            height: 16px;
          }

          .zoomprevIcon {
            position: absolute;
            width: 16px;
            height: 16px;
          }

          .zoomnextIcon {
            position: absolute;
            width: 16px;
            height: 16px;
          }

          .panIcon {
            position: absolute;
            width: 16px;
            height: 16px;
          }

          .deactivateIcon {
            position: absolute;
            width: 16px;
            height: 16px;
          }
      </style> 

      <script src="https://js.arcgis.com/3.15/"></script>
      <script> 
        var map;
        require([
          "esri/map",
          "esri/dijit/BasemapGallery",
           "esri/dijit/HomeButton",
           "esri/toolbars/navigation",
            "dojo/on",
             "dojo/parser",
            "dijit/registry",
            "dijit/Toolbar",
            "dijit/form/Button",
          "dojo/domReady!"
        ], function(
          Map, 
          BasemapGallery,
          HomeButton,
          Navigation, 
          on,
          parser,
          registry
        ) {

      parser.parse();

            var navToolbar;
          map = new Map("map", {
            basemap: "topo",
            center: [-105.255, 40.022],
            zoom: 13,
            slider:false
          });

          //add the basemap gallery, in this case we'll display maps from ArcGIS.com including bing maps
          var basemapGallery = new BasemapGallery({
            showArcGISBasemaps: true,
            map: map
          }, "basemapGallery");
          basemapGallery.on('load',function(){
            basemapGallery.remove('basemap_1');
             basemapGallery.remove('basemap_2');
              basemapGallery.remove('basemap_3');
               basemapGallery.remove('basemap_4');
                basemapGallery.remove('basemap_5');
                 basemapGallery.remove('basemap_8');
          });
          basemapGallery.startup();

          basemapGallery.on("error", function(msg) {
            console.log("basemap gallery error:  ", msg);
          });
             var home = new HomeButton({
            map: map
          }, "HomeButton");
          home.startup();

           navToolbar = new Navigation(map);
              on(navToolbar, "onExtentHistoryChange", extentHistoryChangeHandler);

              registry.byId("zoomin").on("click", function () {
                navToolbar.activate(Navigation.ZOOM_IN);
              });

              registry.byId("zoomout").on("click", function () {
                navToolbar.activate(Navigation.ZOOM_OUT);
              });

              registry.byId("zoomfullext").on("click", function () {
                navToolbar.zoomToFullExtent();
              });

              registry.byId("zoomprev").on("click", function () {
                navToolbar.zoomToPrevExtent();
              });

              registry.byId("zoomnext").on("click", function () {
                navToolbar.zoomToNextExtent();
              });

              registry.byId("pan").on("click", function () {
                navToolbar.activate(Navigation.PAN);
              });

              registry.byId("deactivate").on("click", function () {
                navToolbar.deactivate();
              });

              function extentHistoryChangeHandler () {
                registry.byId("zoomprev").disabled = navToolbar.isFirstExtent();
                registry.byId("zoomnext").disabled = navToolbar.isLastExtent();
              }
        });
      </script> 
    </head> 

    <body class="claro"> 

        <div id="map">
         <div id="navToolbar" data-dojo-type="dijit/Toolbar">
          <div data-dojo-type="dijit/form/Button" id="zoomin"  data-dojo-props="iconClass:'zoominIcon'">Zoom In</div>
          <div data-dojo-type="dijit/form/Button" id="zoomout" data-dojo-props="iconClass:'zoomoutIcon'">Zoom Out</div>
          <div data-dojo-type="dijit/form/Button" id="zoomfullext" data-dojo-props="iconClass:'zoomfullextIcon'">Full Extent</div>
          <div data-dojo-type="dijit/form/Button" id="zoomprev" data-dojo-props="iconClass:'zoomprevIcon'">Prev Extent</div>
          <div data-dojo-type="dijit/form/Button" id="zoomnext" data-dojo-props="iconClass:'zoomnextIcon'">Next Extent</div>
          <div data-dojo-type="dijit/form/Button" id="pan" data-dojo-props="iconClass:'panIcon'">Pan</div>
          <div data-dojo-type="dijit/form/Button" id="deactivate" data-dojo-props="iconClass:'deactivateIcon'">Deactivate</div>
        </div>
         <div id="HomeButton"></div>
            <div id="switch" data-dojo-type="dijit/TitlePane" data-dojo-props="title:'Switch Basemap', closable:false, open:false">        
                 <div  id="basemapGallery"></div>
          </div>
        </div>

    </body> 

    </html>

1条回答
狗以群分
2楼-- · 2019-05-21 00:48

parser.parse returns a deferred in dojo 1.8+

what this means is that after

parser.parse() 

your widgets are not necessarily instantiated and ready to be referenced as widgets via dijit/registry.

Also there is this is directly from the Dojo reference guide:

Note that waiting for dojo/domReady! to fire is often not sufficient when working with widgets. Many widgets shouldn’t be initialized or accessed until the following modules load and execute:

  • dojo/uacss
  • dijit/hccss
  • dojo/parser

Thus when working with widgets you should generally put your code inside of a dojo/ready() callback:

you do this by including "dojo/ready" in your require array and then wrapping any widget code in

ready(function(){
    ...your widget code....
})

in your case you could probably just wrap your entire javascript code in a ready function

 require([
    "esri/map",
    "esri/dijit/BasemapGallery",
    "esri/dijit/HomeButton",
    "esri/toolbars/navigation",
    "dojo/on",
    "dojo/parser",
    "dijit/registry",
    "dojo/ready",
    "dijit/Toolbar",
    "dijit/form/Button",
    "dojo/domReady!"
], function(
    Map,
    BasemapGallery,
    HomeButton,
    Navigation,
    on,
    parser,
    registry,
    ready
) {
    ready(function() {
        var navToolbar;
        map = new Map("map", {
            basemap: "topo",
            center: [-105.255, 40.022],
            zoom: 13,
            slider: false
        });

...etc

I also like to use parseOnLoad = true which I find to be less prone to errors (both human and otherwise)

Just put this script element above the arcgis js script tag like so

<script type="text/javascript">
var dojoConfig = {
    parseOnLoad: true
};
</script>
<script src="https://js.arcgis.com/3.15/"></script>

and get rid of the call to parser.parse() at the top of your script.

查看更多
登录 后发表回答