繁体   English   中英

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

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

对于尝试学习AMD风格的Dojo时看到的某些行为,我确实感到困惑。 当我实例化模块/对象时,“ this”是指构造函数中的对象。 我对内部函数进行了调用,该内部函数中的“ this”是指Window对象。 因此,当我访问this.attachMapEventHandlers时,出现“对象[对象全局]没有方法'attachMapEventHandlers'”错误。 我究竟做错了什么? 更新:我找到了lang.hitch,这似乎表明异步的性质正在使我绊倒,但是我对如何实现解决方案感到困惑。

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

您可以采取一些措施来解决此问题。

首先,您可以将所需的依赖项添加到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();
    });
},

编辑:你的第三个选择是使用lang.hitch,它可以让你指定的范围this在回调函数。 要使用它,您可以将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
        }));
    }

  });
});

我强烈建议您选择第一个选项,因为它与AMD的整个用法是一致的(声明模块在执行之前需要什么依赖关系,而不是动态加载它)。

您可以将'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