简体   繁体   English

Dojo AMD模块更改“ this”的引用

[英]Dojo AMD module changes reference of “this”

I'm really confused as to some behavior I'm seeing in trying to learn the AMD style of Dojo. 对于尝试学习AMD风格的Dojo时看到的某些行为,我确实感到困惑。 When I instantiate my module/object, "this" refers to the object in my constructor. 当我实例化模块/对象时,“ this”是指构造函数中的对象。 I make a call to an internal function, and "this" inside that internal function refers to the Window object. 我对内部函数进行了调用,该内部函数中的“ this”是指Window对象。 So when I get to this.attachMapEventHandlers I get a "Object [object global] has no method 'attachMapEventHandlers'" error. 因此,当我访问this.attachMapEventHandlers时,出现“对象[对象全局]没有方法'attachMapEventHandlers'”错误。 What am I doing wrong? 我究竟做错了什么? UPDATE: I found lang.hitch, which seems to indicate that the async nature is what's tripping me up, but I'm confused on how to implement a solution. 更新:我找到了lang.hitch,这似乎表明异步的性质正在使我绊倒,但是我对如何实现解决方案感到困惑。

my script inside index.html: 我在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: 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();
        });
    },

There are a couple of things that you could do to resolve this. 您可以采取一些措施来解决此问题。

Firstly, you could add your required dependency to the define array so you don't need to do an asynchronous require within the constructor of the class. 首先,您可以将所需的依赖项添加到define数组,这样就无需在类的构造函数中执行异步要求。

That would look like: 看起来像:

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

OR you could save the current scope of this to something in the closure when doing the require 或者你可以的电流范围保存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: your third option would be using lang.hitch, which lets you specify the scope of this in the the callback function. 编辑:你的第三个选择是使用lang.hitch,它可以让你指定的范围this在回调函数。 To use it, you would add dojo/_base/lang to you define() dependency list, and wrap the require callback in lang.hitch(this, function(){}); 要使用它,您可以将dojo/_base/lang添加到define()依赖项列表中,并将require回调包装在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
        }));
    }

  });
});

I would strongly suggest going with the first option, since it is consistent with the entire use of AMD (declaring what dependencies a module needs before it executes, rather than loading it on the fly). 我强烈建议您选择第一个选项,因为它与AMD的整个用法是一致的(声明模块在执行之前需要什么依赖关系,而不是动态加载它)。

You can put 'this' in another variable, like _this, and use _this in your internal function,like 您可以将'this'放在另一个变量中,例如_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(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM