2013-10-03 4 views
1

Я действительно смущен в отношении какого-то поведения, которое я вижу, пытаясь изучить стиль Dojo в стиле AMD. Когда я создаю экземпляр модуля/объекта, «это» относится к объекту в моем конструкторе. Я делаю вызов внутренней функции, а «это» внутри этой внутренней функции относится к объекту Window. Поэтому, когда я добираюсь до this.attachMapEventHandlers, я получаю «Object [object global] не имеет ошибки« attachMapEventHandlers »метода. Что я делаю не так? UPDATE: я нашел lang.hitch, что, по-видимому, указывает на то, что асинхронный характер - это то, что меня отключает, но я смущен тем, как реализовать решение.Модуль Dojo AMD меняет ссылку на «this»

мой сценарий внутри index.html:

require(["javascript/layout", "dijit/layout/ContentPane", "dijit/layout/BorderContainer", "dijit/layout/AccordionContainer", 
     "dojo/dom", "dojo/dom-attr", "dijit/Toolbar", "dijit/form/Button", "dijit/Dialog","dijit/ProgressBar", "dojo/domReady!"], 
     function (layout, dom, domAttr) { 
      mapControl = new layout(); 

layout.js:

define(["dojo/_base/declare"], function(declare) { 
return declare(null, { 
    action:"pan", 
    activeMeasureTool:"", 
    aerialLayer:"", 
    legendLayers:"", 
    loadedServices:"", 
    popup:"", 
    resizeId:0, 
    constructor: function() { 
     this.init(); 
    }, 
    init: function() { 
     require(["esri/map", "esri/config", "esri/SpatialReference", "esri/geometry/Extent"], 
      function(Map, config, SpatialReference, Extent) { 
      //custom map requires a proxy to function properly. 
      esri.config.defaults.io.proxyUrl = "../sdc_devdata/proxy.php"; 

      var spatRef = new SpatialReference(2276); 

      var startExtent = new Extent(2481416.32087491, 6963246.42495962, 2501196.36936991, 6980267.92469462, spatRef); 
      var appFullExtent = new Extent(2396699.46935379, 6872369.60195443, 2607745.94404633, 7107335.22319087, spatRef); 

      map = new Map("map", {extent: startExtent, isZoomSlider:true, logo:false, sliderStyle:"large"}); 
      this.attachMapEventHandlers(); 
      this.createLayers(); 
      this.handleLayerVisibilityChange(); 
     }); 
    }, 

ответ

0

Вы можете поставить 'это' в другой переменной, как _this и использовать _this в вашей внутренней функции, подобный

init: function() { 
     var _this= this; 
     require(["esri/map", "esri/config", "esri/SpatialReference", "esri/geometry/Extent"], 
      function(Map, config, SpatialReference, Extent) { 
      ... 
      _this.attachMapEventHandlers(); 
      _this.createLayers(); 
      _this.handleLayerVisibilityChange(); 
1

Есть несколько вещей, которые вы можете сделать, чтобы решить эту проблему.

Во-первых, вы можете добавить свою необходимую зависимость к массиву define, поэтому вам не нужно выполнять асинхронное требование внутри конструктора класса.

Это будет выглядеть так:

define(["dojo/_base/declare", "esri/map", "esri/config", "esri/SpatialReference", "esri/geometry/Extent"], function (declare, Map, config, SpatialReference, Extent) { 
    return declare(null, { 
    action: "pan", 
    activeMeasureTool: "", 
    aerialLayer: "", 
    legendLayers: "", 
    loadedServices: "", 
    popup: "", 
    resizeId: 0, 
    constructor: function() { 
     this.init(); 
    }, 
    init: function() { 
     //custom map requires a proxy to function properly. 
     esri.config.defaults.io.proxyUrl = "../sdc_devdata/proxy.php"; 

     var spatRef = new SpatialReference(2276); 

     var startExtent = new Extent(2481416.32087491, 6963246.42495962, 2501196.36936991, 6980267.92469462, spatRef); 
     var appFullExtent = new Extent(2396699.46935379, 6872369.60195443, 2607745.94404633, 7107335.22319087, spatRef); 

     map = new Map("map", { 
     extent: startExtent, 
     isZoomSlider: true, 
     logo: false, 
     sliderStyle: "large" 
     }); 
     this.attachMapEventHandlers(); 
     this.createLayers(); 
     this.handleLayerVisibilityChange(); 
    } 
    }); 
}); 

ИЛИ вы можете сохранить текущий объем this к чему-то в замыкании при выполнении Требовать

init: function() { 
    var that = this; 
    require(["esri/map", "esri/config", "esri/SpatialReference", "esri/geometry/Extent"], 
    function (Map, config, SpatialReference, Extent) { 
     //custom map requires a proxy to function properly. 
     esri.config.defaults.io.proxyUrl = "../sdc_devdata/proxy.php"; 

     var spatRef = new SpatialReference(2276); 

     var startExtent = new Extent(2481416.32087491, 6963246.42495962, 2501196.36936991, 6980267.92469462, spatRef); 
     var appFullExtent = new Extent(2396699.46935379, 6872369.60195443, 2607745.94404633, 7107335.22319087, spatRef); 

     map = new Map("map", { 
     extent: startExtent, 
     isZoomSlider: true, 
     logo: false, 
     sliderStyle: "large" 
     }); 
     that.attachMapEventHandlers(); 
     that.createLayers(); 
     that.handleLayerVisibilityChange(); 
    }); 
}, 

EDIT: Ваш третий вариант будет использовать языки .hitch, который позволяет указать область this в функции обратного вызова. Для того, чтобы использовать его, вы бы добавить dojo/_base/lang вам определить() список зависимостей, и оберните требуют обратного вызова в lang.hitch(this, function(){});

define(["dojo/_base/declare", "dojo/_base/lang"], function (declare, lang) { 
    return declare(null, { 
    //... 
    init: function() { 
     require(["esri/map", "esri/config", "esri/SpatialReference", "esri/geometry/Extent"], 
     lang.hitch(this, function (Map, config, SpatialReference, Extent) { 
      //this now refers to the instance of the class 
     })); 
    } 

    }); 
}); 

Я настоятельно рекомендую идти с первым вариантом, так как она соответствует всем использованию AMD (объявляя, какие зависимости требуется модулю до его выполнения, а не загружать его на лету).

+0

Я ценю ваш ответ. Принял первый – Shawn

Смежные вопросы