2

我有这样的ArcGIS Javascript代码:

<script type="text/javascript">
      require(["dojo/ready",
      "dgrid/OnDemandGrid",
      "dgrid/Selection",
      "dojo/store/Memory", 
      "dojo/_base/array",
      "dojo/dom-style",
      "dijit/registry",
      "esri/map", 
      "esri/dijit/Popup",
      "esri/dijit/PopupTemplate",
      "esri/layers/FeatureLayer",
      "dojo/dom-class",
      "dojo/dom-construct",
      "dojo/on", 
      "esri/InfoTemplate",
      "esri/symbols/SimpleLineSymbol",
      "esri/symbols/SimpleFillSymbol",
      "esri/tasks/QueryTask",
      "esri/tasks/query",
      "dojo/_base/declare", 
      "dojo/number", 
      "dojo/on",
      "dojox/charting/Chart",
      "esri/renderers/UniqueValueRenderer",
      "dojo/parser",
      "dojo/_base/Color", 
      "dijit/layout/BorderContainer",
      "dijit/layout/ContentPane"
      ], function (
        ready,
        Grid, 
        Selection, 
        Memory, 
        array,
        domStyle,
        registry,
        Map,
        Popup,
        PopupTemplate, 
        FeatureLayer,
        domClass,
        domConstruct,
        on, 
        InfoTemplate,
        SimpleLineSymbol,
        SimpleFillSymbol,
        QueryTask,
        Query,
        declare, 
        dojoNum, 
        on,
        Chart, 
        UniqueValueRenderer,
        parser
      ) {
        ready(function() {

          parser.parse();

          var popup = Popup({
            titleInBody: false
          },domConstruct.create("div"));

          // create the dgrid
          window.grid = new (declare([Grid, Selection]))({
            // use Infinity so that all data is available in the grid
            bufferRows: Infinity,
            columns: {
              "FID": "FID",
              "PROV": "PROV"
            }
          }, "grid");
          // add a click listener on the ID column
          grid.on(".field-id:click", selectState);

          var initialExtent = new esri.geometry.Extent({"xmin":89.971,"ymin":-12.472,"xmax":144.301,"ymax":9.511,"spatialReference":{"wkid":4326}});
          map = new esri.Map("map", { extent: initialExtent,infoWindow: popup});

          //var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer");
          var basemap2 = new esri.layers.ArcGISDynamicMapServiceLayer("http://localhost:6080/arcgis/rest/services/BaseMap/Peta_Dasar_Indonesia_Colors/MapServer",{"opacity":0.4});
          map.addLayer(basemap2);
          //map.addLayer(basemap);


          domClass.add(window.map.infoWindow.domNode, "myTheme");
            var template = new PopupTemplate({
            title: "Data Luas Lahan Sawah {PROV}",
            description: "of starters from {PROV} finished",
          });

          window.statesUrl = "http://localhost:6080/arcgis/rest/services/BaseMap/Peta_Dasar_Indonesia_Colors/MapServer/8";
          window.outFields = ["FID","PROV"];

          var fl = new FeatureLayer(window.statesUrl, {
            id: "stat",
            mode: 1, // ONDEMAND, could also use FeatureLayer.MODE_ONDEMAND
            infoTemplate:template,
            outFields: window.outFields
          });

          fl.on("load", function() {
            fl.maxScale = 0; // show the states layer at all scales
            fl.setSelectionSymbol(new SimpleFillSymbol().setOutline(null).setColor("#AEC7E3"));
          });

          fl.on("click", selectGrid);

          // change cursor to indicate features are click-able
          fl.on("mouse-over", function() {
            map.setMapCursor("pointer");
          });
          fl.on("mouse-out", function() {
            map.setMapCursor("default");
          });


          map.addLayer(fl);

          map.on("load", 
            function addFeatureLayer() {
              var defaultSymbol = new SimpleFillSymbol().setStyle(SimpleFillSymbol.STYLE_NULL);
              defaultSymbol.outline.setStyle(SimpleLineSymbol.STYLE_NULL);

              //create renderer
              var renderer = new UniqueValueRenderer(defaultSymbol, "PROV");

              //add symbol for each possible value
              renderer.addValue("Banten", new SimpleFillSymbol().setColor("#00FA1D"));
              renderer.addValue("Dki Jakarta", new SimpleFillSymbol().setColor("#FA0000"));
              renderer.addValue("Jawa Barat", new SimpleFillSymbol().setColor("#FAFA00"));
              renderer.addValue("Jawa Tengah", new SimpleFillSymbol().setColor("#00FA1D"));
              renderer.addValue("Daerah Istimewa Yogyakarta", new SimpleFillSymbol().setColor("#FAFA00"));
              renderer.addValue("Jawa Timur", new SimpleFillSymbol().setColor("#FAFA00"));
              var template = new PopupTemplate({
                title: "Data {PROV}",
                description: "Data Luas Lahan Sawah {PROV}",
              });
              var featureLayer = new FeatureLayer("http://localhost:6080/arcgis/rest/services/BaseMap/Peta_Dasar_Indonesia_Colors/MapServer/8", {
                mode: 1, // ONDEMAND, could also use FeatureLayer.MODE_ONDEMAND
                infoTemplate:template,
                outFields: window.outFields
              });

              featureLayer.setRenderer(renderer);
              map.addLayer(featureLayer);
            } ,
            function( evt ){
              // show the border container now that the dijits 
              // are rendered and the map has loaded
              domStyle.set(registry.byId("container").domNode, "visibility", "visible");
              populateGrid(Memory); // pass a reference to the MemoryStore constructor
          });

          function populateGrid(Memory) {
            var qt = new QueryTask(window.statesUrl);
            var query = new Query();
            query.where = "1=1";
            query.returnGeometry = false;
            query.outFields = window.outFields;
            qt.execute(query, function(results) {
              var data = array.map(results.features, function(feature) {
                return {
                  // property names used here match those used when creating the dgrid
                  "FID": feature.attributes[window.outFields[0]],
                  "PROV": feature.attributes[window.outFields[1]]
                }
              });
              var memStore = new Memory({ data: data });
              window.grid.set("store", memStore);
            });
          }
          // fires when a row in the dgrid is clicked
          function selectState(e) {
            // select the feature
            var fl = map.getLayer("stat");
            var query = new Query();
            query.objectIds = [parseInt(e.target.innerHTML)];
            fl.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(result) {
              if ( result.length ) {
                // re-center the map to the selected feature
                window.map.centerAt(result[0].geometry.getExtent().getCenter());
              } else {
                console.log("Feature Layer query returned no features... ", result);
              }
            });
          }

          // fires when a feature on the map is clicked
          function selectGrid(e) {
            var profinsi = e.graphic.attributes.PROV;
            var id = e.graphic.attributes.FID;
            // select the feature that was clicked
            var query = new Query();
            query.objectIds = [id];
            var states = map.getLayer("stat");
            states.selectFeatures(query, FeatureLayer.SELECTION_NEW);
            // select the corresponding row in the grid
            // and make sure it is in view
            grid.clearSelection();
            grid.select(id);
          }

          function test(){
            alert("alert");
          }
        });
    });
</script>

我想在 dojo.ready 函数中调用函数。例如,我想用 onclick 调用函数 test() :

<input type="submit" value="Submit" onclick="test();">

但仍然无法正常工作。
谁能帮我解释一下如何在 dojo.ready 中调用函数?

4

1 回答 1

4

这是因为在文档中编写事件处理程序是一种不好的做法。如果您在函数内添加函数,它们的作用域是该函数(这意味着,它们只能从ready()函数内部访问,而不能从 DOM(= 从 HTML 页面)访问。

用正常的话来说:“按钮看不到函数 test()”。

你可以通过两种方式解决这个问题:

第一种方法是test()通过将函数移出ready()回调通过以下方式替换函数来全局范围限定函数:

test = function() {
    alert("alert");
};

因为您没有var在变量前面放置 a test,这意味着它现在是全局范围的,这意味着可以从 DOM 访问它。但是,我不推荐它,这被认为是一种不好的做法。谷歌搜索“为什么全局变量是不好的 javascript”可以让您大致了解它为什么不好。


第二种可能性是通过使用模块或模块将事件声明本身移动到ready()范围内,例如:dojo/ondojo/query

require(["dojo/ready", "dojo/query"], function(ready, query) {
    ready(function() {
        query("input[type=\"submit\"]").on("click", test);

        function test() {
            alert("test");
        }
    });
});

还有一个 JSFiddle:http: //jsfiddle.net/g00glen00b/tLN5b/

这可以被认为是一种更好的做法,因为您没有使用全局命名空间并且您可以定义事件处理程序。

于 2013-12-20T13:51:54.930 回答