【问题标题】:Dojo - Promise Can't Access VariablesDojo - Promise 无法访问变量
【发布时间】:2015-11-03 15:46:08
【问题描述】:

我在 ESRI Web App Builder 中使用 dojo,遇到了一种情况,即我需要运行 AJAX 调用并仍然从基类访问变量。下面是我的代码,其中包含 cmets,以准确解释它在哪里成功以及在哪里失败:

define(['dojo/_base/declare', 'jimu/BaseWidget', 'dojo/request', "esri/layers/WMSLayer", "esri/config", "dojo/domReady!"], function (declare, BaseWidget, request, WMSLayer, esriConfig) {

    return declare([BaseWidget], {
        baseClass: 'jimu-widget-mywidget',
        // This function is called by a button press (Normally the WMSLayer variable would be set by user input)
        addWms: function () {
            var wmsLayer = new WMSLayer("http://sampleserver1.arcgisonline.com/ArcGIS/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/WMSServer", {
                format: "png",
                visibleLayers: [2]
            });

            this.map.addLayer(wmsLayer); // this.map is inherited from BaseWidget as far as I can see. This adds a wms to my map without error

            request("request.html").then(function(data){
                var wmsLayer = new WMSLayer("http://sampleserver1.arcgisonline.com/ArcGIS/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/WMSServer", {
                    format: "png",
                    visibleLayers: [2]
                });

                this.map.addLayer(wmsLayer); // This is now in another context....I get the error HERE. 
                // At this point map is not defined because this anonymous function is running
                // in a different context. ( at least I think that's what is happening )
            }, function(err){
                // Hopefully there are no typos in my example XD
            });
        }
    });
});

我的问题是 --> 如何通过“request”的回调函数访问“map”变量?

我希望能够从我对 WMS 服务的 GetCapabilities 的调用中运行 this.map.addLayers。该请求通常会调用它,我一直到我的代码结束,直到我无法再访问“map”变量,因为我知道它。

Dojo 类型的答案是首选,但普通的旧 javaScript 也可以。请避免使用 JQuery 答案。

资源是:
ESRI JavaScript library
Dojo
ESRI Web App Builder

【问题讨论】:

    标签: javascript dojo esri wms arcgis-js-api


    【解决方案1】:

    您遇到的问题是调用异步回调时执行上下文丢失的经典问题(因此this 不再意味着您想要的)。通常有两种方法可以解决此问题。

    一种方法是在外部范围内创建一个引用 this 的变量,以便内部函数可以访问它:

    var self = this;
    request('request.html').then(function (data) {
        // ...
    
        self.map.addLayer(wmsLayer);
    });
    

    另一种方法是使用上下文绑定,通过Function#bind (ES5) 或dojo/_base/lang.hitch

    // Function#bind:
    request('request.html').then(function (data) {
        // ...
    
        this.map.addLayer(wmsLayer);
    }.bind(this));
    
    // lang.hitch:
    request('request.html').then(lang.hitch(this, function (data) {
        // ...
    
        this.map.addLayer(wmsLayer);
    }));
    

    将异步处理函数分解为另一个内部实例方法的绑定方法也很常见:

    _addRequestedLayer: function () {
        // ...
    
        this.map.addLayer(wmsLayer);
    },
    
    addWms: function () {
        // ...
    
        // ES5:
        request('request.html').then(this._addRequestedLayer.bind(this));
        // ...or lang.hitch, with late binding:
        request('request.html').then(lang.hitch(this, '_addRequestedLayer'));
    

    还有一个tutorial on lang.hitch

    【讨论】:

    • 将此标记为答案,因为它是我使用的答案。不过两者都有效。
    【解决方案2】:

    在您的请求回调中,this 不再引用您的类。在回调中访问地图的一种简单方法是在 addWms 函数范围内的变量中分配地图的引用,然后在回调中使用它:

    addWms: function() {
        var map = this.map;
        // Your code here
        request('request.html').then(function (data) {
            // Your code here
            map.addLayer(wmsLayer); // Note that you're using map instead of this.map
        }
    }
    

    您还可以使用 Dojo hitch 函数,您可以在其中传递一个函数以及应该应用它的上下文。我建议你看看这个链接http://dojotoolkit.org/reference-guide/1.10/dojo/_base/lang.html#hitch

    【讨论】:

      猜你喜欢
      • 2016-11-08
      • 1970-01-01
      • 2020-12-13
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      • 2021-09-22
      • 2018-10-17
      相关资源
      最近更新 更多