使用 esri-loader 和 TypeScript 进行 ArcGIS JS API 开发

3
分享 2020-09-14
ArcGIS JS API 基于古老的 JavaScript 框架 Dojo 开发, dojo 虽然是曾经的王者, 但是 2020 年的前端 Web 开发, 早已是 Angular、 React 和 Vue 三大框架的天下, JavaScript 的新特性可以说是日新月异, 老旧的 dojo 都没有跟进。 同时国内也几乎没有人/组织再基于 dojo 进行 Web 开发,所以很多前端 Web 开发开发者都会觉得 ArcGIS JS API 不太友好, 感觉很难用起来。
 
esri-loader 是 ESRI 官方开源的加载器, 对 dojo 的加载器进行封装, 转换成 ES6 标准的 Promise 模式进行加载, 可以比较方便的在 ES6+ 的环境中使用。 esri-loader 使用 TypeScript 开发, 以 npm 包的形式发布, 可以很方便的使用 npm 来下载和部署。
 
TypeScript 也就不用多说了, 它在 JavaScript 的基础上增加了类型系统, 现在也是非常的流行。 几乎所有的 JavaScript 框架都对 TypeScript 提供了支持。
 
根据 ArcGIS JS API 的发行说明中的描述, 大约有 96% 的代码直接使用 TypeScript 进行开发, 提供了完整的 TypeScript 类型定义 @types/arcgis-js-api , 所以说 ArcGIS JS API 对 TypeScript 的支持也是非常好的。
 
使用 TypeScript 开发, 可以得到:
 
  • 使用更加高级的 JavaScript 语法, ES6 的 class , ES2017 的 async/await 等;
  • 严格的静态类型与拼写检查;
  • 基于上下文的精准智能提示;


Screen_Shot_2020-08-30_at_15.50_.28_.png

Screen_Shot_2020-08-30_at_15.51_.27_.png

Screen_Shot_2020-08-30_at_15.52_.24_.png

 
在 ArcGIS JS API 的文档中, 给出的例子都是这样子的:
require(['esri/Map', 'esri/views/SceneView'], function(Map, SceneView) {
// init map and sceie view in callback
var map = new Map({ basemap: 'satellite' });
var mapView = new SceneView({
map: map,
container: 'viewDiv',
extent: { /* ... */ }
});
})
而使用 esri-loader 的话, 看起来是这样子的:
const [Map, SceneView] = await esriLoader.loadModules(['esri/Map', 'esri/views/SceneView']);
const map = new Map({ basemap: 'satellite' });
const mapView = new SceneView({
map: map,
container: 'viewDiv',
extent: { /* ... */ }
});
esri-loader 提供的 loadModules 对 require 函数进行了二次封装, 返回 ES 标准的 Promise , 可以方便的在更加高级的 JavaScript 环境中使用, 同时也尽可能的避免了 dojo 框架的入侵性。 再结合 TypeScript , 代码就会变成这样子:
import { loadScript, loadModules } from 'esri-loader';

export class MapApp {

private mapView: __esri.MapView;

/** Load ArcGIS JS API scripts. */
async loadScript() {
const AGS_SDK = 'https://js.arcgis.com/4.16';
await loadScript({
url: `${AGS_SDK}/init.js`,
css: `${AGS_SDK}/esri/themes/light/main.css`
});
}

/** Init a map view */
async initMap(container) {
const [Map, MapView] = await loadModules<[__esri.MapConstructor, __esri.MapViewConstructor]>(['esri/Map', 'esri/views/MapView']);
const map = new Map({ basemap: 'satellite' });
this.mapView = new MapView({
map, container,
extent: {
// autocasts as new Extent()
xmin: -9177811,
ymin: 4247000,
xmax: -9176791,
ymax: 4247784,
spatialReference: { wkid: 102100 }
}
});
}

/** add a feature layer to map */
async addFeatureLayer() {
const [FeatureLayer] = await loadModules(['esri/layers/FeatureLayer']);
const layer = new FeatureLayer({
url: 'https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0'
});
this.mapView.map.layers.add(layer);
}

}

 
StackBlitz 提供了在线的 TypeScript 开发工具, 与兴趣的小伙伴可以在线体验一下使用本文的使用 TypeScript 进行 ArcGIS JS API 开发例子。 
 
如果有兴趣进一步了解, 可以阅读我的这篇文章 使用现代化的脚本进行 ArcGIS JS API 开发

0 个评论

要回复文章请先登录注册