如何让 arcgis require 里定义的方法可以在全局访问?

如何让 arcgis require 里定义的方法可以在全局访问?

在用到 arcgis 的项目里(特别是基于 jquery 的老项目),大多数方法都会用到 arcgis require 进来的东西,那就得写到 require 的回调函数里,此时的方法就变成了局部的了,无法在 HTML 中直接调用这个方法...很蛋疼...!!!???

方法一:将方法赋值到 window 这个全局对象的属性上

require([
    "esri/map",
    "esri/layers/ArcGISDynamicMapServiceLayer",
    "esri/toolbars/navigation",
    "esri/geometry/Extent",
    "esri/SpatialReference",
    "dojo/domReady!"],
        function (Map, ArcGISDynamicMapServiceLayer, Navigation, Extent, SpatialReference) {
    // ...

    // 将 loadgeojsonstring 方法暴露到全局,让 html 里面可以调用(window.loadgeojsonstring 前面不加 var)
    window.loadgeojsonstring = loadgeojsonstring;
    function loadgeojsonstring (obj){
        var polygonJson = {
            "spatialReference": mainMap.spatialReference
        };
        polygonJson.rings =eval('(' + obj + ')');
        poly = new Polygon(polygonJson);
        var symbol = new SimpleFillSymbol(
            SimpleFillSymbol.STYLE_SOLID,
            new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([255, 0, 0]), 2),
          	new Color([100, 100, 100, 0.75])
        );
        var graphic = new Graphic(poly, symbol);
        mainMap.graphics.add(graphic);
        mainMap.setExtent(poly.getExtent().expand(2));
    }

});

方法二:将这个内部方法赋值到一个全局变量上

外部定义作用域更大的变量,内部赋值给它(推荐,不会污染 window 对象)

  • 因为 arcgis 的 require 回调函数会自动调用,故这个赋值会自动被调用
var loadgeojsonstring;

require([
    "esri/map",
    "esri/layers/ArcGISDynamicMapServiceLayer",
    "esri/toolbars/navigation",
    "esri/geometry/Extent",
    "esri/SpatialReference",
    "dojo/domReady!"],
        function (Map, ArcGISDynamicMapServiceLayer, Navigation, Extent, SpatialReference) {
    // ...

    // 将 loadgeojsonstring 方法暴露到全局,让 html 里面可以调用
    loadgeojsonstring = function (obj){
        var polygonJson = {
            "spatialReference": mainMap.spatialReference
        };
        polygonJson.rings =eval('(' + obj + ')');
        poly = new Polygon(polygonJson);
        var symbol = new SimpleFillSymbol(
            SimpleFillSymbol.STYLE_SOLID,
            new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([255, 0, 0]), 2),
            new Color([100, 100, 100, 0.75])
        );
        var graphic = new Graphic(poly, symbol);
        mainMap.graphics.add(graphic);
        mainMap.setExtent(poly.getExtent().expand(2));
    }

});

验证推理 demo

  • 像下面这个 demo,如果不去调用方法 b,那么在全局是无法通过 a 访问到 b 里面定义那个方法的
  • 一旦方法 b 被调用过后,就可以在全局通过 a 访问到 b 里面定义的方法了
  • 因为方法在定义的时候并不会去执行内部的代码,故函数赋值并未生效
let a;
let b = () => {
    c = 123
    a = function() {
        // 这里可以访问到只在 b 作用域里有的数据 c,在外部是无法访问的
        console.log("内部方法执行了...")
    }
}

a
// undefined

b()
// undefined

a()
// 内部方法执行了...

原理剖析总结

方法定义的时候会读取上下文的作用域,而外部变量是外部可访问的,把内部方法赋值给外部变量,就可以在外部访问到这个内部方法了,且这个方法也能访问到局部作用域里的内容

浏览器的 window 就是一个顶级的对象,一般赋值全局变量安全的办法都是把变量绑定在 window 上(我不认同这句话),当然别去覆盖里面默认的变量。

原文地址:https://www.cnblogs.com/suwanbin/p/14757224.html