如何让 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 上(我不认同这句话),当然别去覆盖里面默认的变量。