不知道大家有没有这种体验,我们开始学web开发的时候,会把HTML、JavaScript、CSS代码都堆叠在一个HTML文件中,慢慢地,随着代码量的增多,不同的代码堆叠在一起显得很乱,我们开始把html、css、js独立到不同的文件中。随着JS代码的数量不断增长,JS文件的数量也一样,管理和引用js代码也变得复杂起来,而解决这种问题一个有效的方法就是采用“面向对象(OO)”模式。通过使用面向对象的风格,可以避免应用程序中代码混乱,并且可以增加代码的复用性,简化应用程序后期维护,可以使错误更快地修复,并在更短的时间内实现新功能。
ArcGIS API中的模块
Dojo Toolkit是一个开源的模块化JavaScript库(或更具体地说是JavaScript工具包),Dojo的代码被划分为逻辑单元称之为模块, 这有点类似于Java中的package,模块中可以包含类和简单方法。而ArcGIS API for JavaScript就是建立在Dojo的基础之上,然后增加了自己的模块。
我们平常使用ArcGIS API for JavaScript开发时,首先得require需要用到的类,比如我们要创建一副地图,首先得引用map类:
require(["esri/map"], function(Map) { /* code goes here */ });
如果你在本地部署了ArcGIS API就能看到在esri文件夹下有个map.js文件,我们需要的Map类也就是在这个模块中定义的。
我们可以打开map.js的源码,网上随便找个工具格式化下,折叠declaredClass: "esri.Map"
之后的代码:
可以发现,Map对象的方法和属性都在其中定义。
自己写一个模块
1、使用define()
来加载模块所需的依赖,具体用法可以参考文档。
declare
用于创建一个可以实例化的类,所以必须引用
define(["dojo/_base/declare"],function(declare){
});
2、用declare(className,superclass,props)建一个类
参数 | 类型 | 描述 |
---|---|---|
className | String | 构造函数的可选名称。它将被用作创建的构造函数的全局名称。 |
superclass | Function or Function[] | 可以为空,函数或函数数组。这个参数指定一个继承表(最左边一个是最原始的父类) |
props | Objectid | 定义类属性和方法的对象。通过使其成为一个名为“constructor”的属性来定义一个构造函数。 |
下面这个示例定义一个Geocoder.js
模块,通过创建一个类Geocoder
,调用百度地址逆编码API,将Point转为地址信息。
define(["dojo/_base/declare","dojo/request/script","dojo/json","dojo/dom"],function(declare,script,JSON,dom){
return declare(null, {
ak: null,
constructor: function(){
this.ak="WtSZiDjE0KEgfSMsxGY7pxng";
},
getLocation: function(opt){
var point=opt.point;
var domID=opt.domId;
var detailed=("detailed" in opt)?opt.detailed:false; //默认为false,不显示详细地址信息
var result={};
script.get("http://api.map.baidu.com/geocoder/v2/?coordtype=wgs84ll&location="+opt.point.getLatitude()+","+opt.point.getLongitude()+"&output=json&pois=1&ak="+this.ak, {
jsonp: "callback"
}).then(function(data){
result["description"]=data.result.sematic_description;
result["address"]=data.result.formatted_address;
console.log(result)
if(detailed){
dom.byId(opt.domId).innerHTML=result.address+","+result.description;
}else{
dom.byId(opt.domId).innerHTML=result.description;
}
})
}
})
})
-
constructor
:构造函数,给ak
属性赋值 -
getLocation
:获取地址信息方法,其中opt参数为一个Objectid
opt={
point: //Point对象,逆编码的点
domID: //将地址信息插入的DOM的ID
detailed: //是否详细输出地址信息(true||false)
}
使用自己的模块
在ArcGIS API 文件目录(arcgis_js_api/library/3.20/3.20/)中新建一个文件夹为“gisxxcom”,再将自己写的模块Geocoder.js放入其中。
项目中使用自己的模块:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
<title>Simple Map</title>
<link rel="stylesheet" href="http://115.28.149.107/arcgis_js_api/library/3.20/3.20/esri/css/esri.css">
<style>html, body { height: 100%; width: 100%; margin: 0; padding: 0; } #map{ width: 75%; height: 100%; float: left; } #result{ width: 25%; height: 100%; float: left; }</style>
<script src="http://115.28.149.107/arcgis_js_api/library/3.20/3.20/init.js"></script>
</head>
<body>
<div id="map"></div>
<div id="result">
<h4 id="description"></h4>
</div>
</body>
<script>
require(["esri/map", "esri/geometry/Point", "gisxxcom/Geocoder", "dojo/domReady!"],
function(Map, Point, Geocoder) {
var map = new Map("map", {
basemap: "osm",
center: [116.026, 28.6826],
zoom: "15"
});
var geocoder = new Geocoder();
map.on("click",
function(e) {
console.log(e.mapPoint.getLongitude() + "," + e.mapPoint.getLatitude());
geocoder.getLocation({
point: e.mapPoint,
domId: "description"
});
});
});
</script>
</html>
效果预览:
本文首发微信公众号 :GISXXCOM