背景
最近有个采用React的项目用到了ArcGis,发现跟之前的用法非常不同,而且经过我们调研后发现,相关资料并不多见,并且相当分散,主要集中在github和arcgis for developer上。这也算是踩过的一个比较深的坑,在这里总结一下,希望能帮到大家。
基本原理
要在react中使用arcgis的api可能要比大家想象的要复杂一些,因为arcgis并没有给大家提供标准的react组件,而是要依赖esri-loader-react,esri-loader等多个组件的联合使用才可以。
有时间的同志可以看看看这篇文章,拜读一下大神的文章一切都明白了。
最核心的下面这段话
The ArcGIS API for JavaScript is written in Dojo and distributed as large library of AMD modules. Unfortunately, most module loaders, including webpack, implement the AMD “standard” differently than the way that Dojo does, specifically in the area of plugins. There is a Dojo loader for webpack that tries to address those differences, but as of time of writing it is not capable of loading ArcGIS modules. Even once that issue is resolved, I still think you’ll want to understand the workarounds below so you can decide which is the best solution for your application.
简单的说就是arcgisapi的JavaScript是基于Dojo实现的,并且需要通过AMD模块导入。但是呢,webpack的AMD实现方式与Dojo不同,因此产生了冲突,因此我们需要采用各种奇怪的方法来曲线救国解决这两者的冲突。
在本文中我们采用了建立专用的地图加载模块的方案,即通过esriLoader的dojoRequire来引入arcgis的类。
示例代码如下所示
//导入esri-loader
import * as esriLoader from 'esri-loader';
// 使用dojoRequire来一如esri/map类
esriLoader.dojoRequire(['esri/map'], (Map) => {
// 使用Map类创建地图
let map = new Map('mapNode', {
center: [-118, 34.5],
zoom: 8,
basemap: 'dark-gray'
});
});
实际代码
来跟着我大喊一句,show me the code。
封装控件
import React from 'react';
import { dojoRequire } from 'esri-loader'
import EsriLoader from 'esri-loader-react'
export default class Map extends React.Component {
//采用构造函数的方法解决不用页面同时调用地图组件产生id冲突问题
constructor(props) {
super(props);
let timeStample = new Date().getTime();
this.state = {
mapDivId: "mapdiv" + timeStample,
mainMap: {}
};
}
render() {
const mapOptions = {
url: 'http://ip:8080/arcgis_js_api/library/3.9/3.9/init.js'
}
let flag = this.props.getShowType();
let mapStyle;
if (flag !== "index") {
//使用自适应大小
mapStyle = { height: '400px', width: '430px' };
} else {
mapStyle = { height: '100vh', width: '70vw' };
}
return (
<div>
<EsriLoader options={mapOptions} ready={
() => console.time