vlambda博客
学习文章列表

解析ArcGIS API for JavaScript全新开发模式



01


ArcGIS API for JavaScript的发展进程



ArcGIS API for JavaScript发展至今,已经更新迭代了好几个版本了。相信用过的小伙伴都知道,HTML4时代在页面上使用ArcGIS API for JavaScript还是用着古老的Dojo框架,很大原因是因为ArcGIS API for JavaScript基于Dojo开发因此也离不开Dojo。如今的前端开发早已是React、Vue、Angular三大框架的天下了,Dojo框架没有跟上新的ES6标准,适应不了现代JS的开发环境,使得国内几乎没有人在基于Dojo进行web开发,加上ArcGIS API for JavaScript在本机上部署安装十分麻烦,让很多行业内的前端开发者们觉得ArcGIS API for JavaScript十分的不友好。

后来,Esri官方发布了“esri-loader”,是将Dojo的AMD加载器进行封装并转换成了ES6标准的promise模式进行加载,让ArcGIS API for JavaScript能够很好的在ES6的环境下使用,而且“esri-loader ”是使用 TypeScript 开发,并以 npm 包的形式发布,我们只需要在项目中用npm安装esri-loader库,就可以从ArcGIS CDN托管API的构建中延迟加载模块,快速的在项目中安装部署ArcGIS API for JavaScript,这种方法通常被称为AMD模块构建。


AMD模块构建采用异步的方式加载模块,所以在使用“esri-loader”时想要加载ArcGIS API for JavaScript中的某一个API模块的话,需要通过方法esriLoader.loadModules,按照dojo中require引入模块的写法将模块加载进来,然后才能进行相应的功能开发。尽管在ES6环境下通过AMD模块构建的方法已经能够很好的使用ArcGIS API for JavaScript了,但这却不是一个方便、简洁的开发模式,AMD方法会预先加载所有的依赖,直到使用时候才执行,会浪费掉许多的资源,因此我们更希望的一种开发方式,是能够在代码的顶部引入模块,只执行一次就能够在代码中使用。

而ArcGIS API for JavaScript 4.18与4.19版本的发布彻底打破了这一尴尬的局面。在ArcGIS API for JavaScript4.18发布了ES modules的测试版,我们可以实现直接在组件顶部引入所需的API模块,然后在组件代码任何地方即可使用。紧接着4.19版本真正推出了正式版,一个振奋人心的消息!现在ArcGIS API for JavaScript能够支持ES modules了,这将意味着开发人员能够在不同的框架和工具上更好的使用它。



02


ArcGISAPI for JavaScript的ES modules


ES modules(ESM) 是JavaScript 官方的标准化模块系统,是用于处理模块的 ECMAScript标准,具有高分离、高复用的特点,很好的避免了引用模块时造成的命名冲突,而且现在所有主流的浏览器都能够支持ES modules。新的ArcGIS API for JavaScript的ES modules可以直接通过npm下载,只需短短一条命令:

npm install @arcgis/core

就可以将模块安装到你的项目中了

解析ArcGIS API for JavaScript全新开发模式

                           


03


 在React上使用ArcGIS API for JavaScript


接下来我将通过一个在React框架上的小例子,来展示ArcGIS API for JavaScript的ES modules。

    

首先用脚手架创建一个React的项目


解析ArcGIS API for JavaScript全新开发模式

接着安装ArcGIS API for JavaScript到我们在项目里,在终端输入命令:

npm install @arcgis/core

等待安装完成后,可以在node_modules目录中找到@arcgis/core文件,然后将assets文件复制到public目录中即可完成安装部署(也可以通过命令ncp完成)。

解析ArcGIS API for JavaScript全新开发模式

安装部署完成后,我们将开始实现我们的小例子了,目标是能够在页面上展示一个要素图层。

新建一个组件ArcgisAPI,我们所需要的控件 有“map”、“MapView”、“FeatureLayer”,我们直接在项目的一开始导入这些控件。
import React, {Component} from 'react';import Map from "@arcgis/core/WebMap";import MapView from "@arcgis/core/views/MapView";import FeatureLayer from "@arcgis/core/layers/FeatureLayer";

在render中写好一个div标签,设置好样式,这个标签将作为展示地图的容器。用ref属性给div标签设定好一个标识,标识为对象this.mapin。

render() {      return (          <div ref={this.mapin} style={{              padding: "0",              margin: "0",              height: "500px",              width: "100%"          }}          ></div>      ) }

React的ref属性可以用来绑定render()输出的任何组件上,可以是一个字符串,也可以是一个回调函数或者是对象。因为我们创建好的地图需要一个容器来存放,所以我们需要通过CreateRef方法创建Refs并通过ref属性与容器进行联系,这样当ref属性绑定对象时,该对象下的current属性就指向了绑定的容器了。

我们在componentDidMount函数中定义好一个map实例来定义我们的底图,还有MapView用于呈现地图。在container中引用我们的DOM容器:

 mapin = React.createRef()
    componentDidMount() {= const map = new Map({ basemap: "topo-vector", }) const view = new MapView({ map: map,            container: this.mapin.current, })     }

在App.js中将组件ArcgisAPI引入,运行项目。

解析ArcGIS API for JavaScript全新开发模式

解析ArcGIS API for JavaScript全新开发模式

可以看到基础地图已经展示到我们的页面上了

接着定义一个layer1为FeatureLayer实例,需要通过Portal发布好FeatureLayer图层,然后在实例中插入图层对应的url,最后用map.add方法添加layer1,运行我们的项目。

 const layer1 = new FeatureLayer({ url:                "https://p15v.arcgisonline.cn/server/rest/services/Hosted/quhua/FeatureServer", }) map.add(layer1);

解析ArcGIS API for JavaScript全新开发模式

我们的要素图层完美的加载到了我们网页上了。

完整代码:

import React, {Component} from 'react';import Map from "@arcgis/core/WebMap";import MapView from "@arcgis/core/views/MapView";import FeatureLayer from "@arcgis/core/layers/FeatureLayer";
export default class APP extends Component {    mapin = React.createRef()        componentDidMount() { const map = new Map({ basemap: "topo-vector", }) const view = new MapView({ map: map, container: this.mapin.current, }) const layer1 = new FeatureLayer({ url: "https://www.arcgisonline.cn/server/rest/services/Hosted/quhua/FeatureServer", })        map.add(layer1);//添加图层 }
render() { return ( <div ref={this.mapin} style={{ padding: "0", margin: "0", height: "500px", width: "100%" }} ></div> {/*设置容器*/}        )}}

可以很明显的感觉出,相比于4.18前的 “esri-loader”方法,新的方法不但高效、简洁,并且更适应现在的模块化、组件化编程,是主流浏览器所采用的标准,更加方便前端开发人员的理解和使用。

当然,如果你是函数组件,在对ref使用上还可以更换为react官方更加推崇的Hooks用法。

/*Hook用法*/import React, {useRef, useEffect} from 'react';import Map from "@arcgis/core/WebMap";import MapView from "@arcgis/core/views/MapView";import FeatureLayer from "@arcgis/core/layers/FeatureLayer";
function App() { const mapin=useRef(null); useEffect(() => { const map=new Map({ basemap: "topo-vector", }) const view=new MapView({ map: map, container:mapin.current, }) const layer1 = new FeatureLayer({ url: "https://p15v.arcgisonline.cn/server/rest/services/Hosted/quhua/FeatureServer", }) map.add(layer1); },[]) return <div ref={mapin} style={{ padding: "0", margin: "0", height: "500px", width: "100%"}} ></div>}export default App;


最后,对于 ArcGIS API for JavaScript的新开发模式,你最为感兴趣的的是什么呢?欢迎下方留言分享你的看法。





2021年易智瑞空间信息技术开发者大会


6月3-4日

北京 中国职工之家

识别下方二维码,报名参会