Browse Source

add InfoWindow UI component.

windsome.feng 7 years ago
parent
commit
5bd108c961
10 changed files with 255 additions and 59 deletions
  1. 2 1
      README.md
  2. 0 15
      lib/Polygon.js
  3. 0 15
      lib/Polyline.js
  4. 46 1
      lib/api.js
  5. 1 1
      package.json
  6. 67 1
      src/App.js
  7. 85 0
      src/lib/InfoWindow.js
  8. 0 12
      src/lib/Polygon.js
  9. 0 12
      src/lib/Polyline.js
  10. 54 1
      src/lib/api.js

+ 2 - 1
README.md

@@ -37,7 +37,8 @@ npm start
 5. `MassMarks`为海量点组件,此组件是一个layer图层,因为比traffic, sattelite复杂,需要设置很多属性,所以独立成一个组件.其他图层也可以参考设置成独立组件
 6. `Polygon.js`为多边形控件,可以用来画行政区域图
 7. `Polyline.js`为多折点线组件,可以用来模拟汽车行驶轨迹
-8. 其他组件,有待添加.
+8. `InfoWindow.js`为InfoWindow组件,可以用来显示弹出框
+9. 其他组件,有待添加.
 
 ## 注意事项
 1. `loadScript.js`是用来加载js和css的,希望能确保加载文件的唯一性,可以参考requirejs的实现机制改掉.

+ 0 - 15
lib/Polygon.js

@@ -32,11 +32,6 @@ export var Polygon = function (_Component) {
   }
 
   _createClass(Polygon, [{
-    key: 'componentWillMount',
-    value: function componentWillMount() {
-      debug(__com__, 'componentWillMount', this._entity);
-    }
-  }, {
     key: 'componentDidMount',
     value: function componentDidMount() {
       debug(__com__, 'componentDidMount', this._entity);
@@ -52,16 +47,6 @@ export var Polygon = function (_Component) {
       this._entity = createPolygon(AMap, opts, events);
     }
   }, {
-    key: 'componentWillReceiveProps',
-    value: function componentWillReceiveProps(nextProps) {
-      debug(__com__, 'componentWillReceiveProps', this._entity);
-    }
-  }, {
-    key: 'componentWillUpdate',
-    value: function componentWillUpdate() {
-      debug(__com__, 'componentWillUpdate', this._entity);
-    }
-  }, {
     key: 'componentDidUpdate',
     value: function componentDidUpdate(prevProps) {
       debug(__com__, 'componentDidUpdate', this._entity);

+ 0 - 15
lib/Polyline.js

@@ -32,11 +32,6 @@ export var Polyline = function (_Component) {
   }
 
   _createClass(Polyline, [{
-    key: 'componentWillMount',
-    value: function componentWillMount() {
-      debug(__com__, 'componentWillMount', this.props.children, this._entity);
-    }
-  }, {
     key: 'componentDidMount',
     value: function componentDidMount() {
       debug(__com__, 'componentDidMount', this.props.children, this._entity);
@@ -52,16 +47,6 @@ export var Polyline = function (_Component) {
       this._entity = createPolyline(AMap, opts, events);
     }
   }, {
-    key: 'componentWillReceiveProps',
-    value: function componentWillReceiveProps(nextProps) {
-      debug(__com__, 'componentWillReceiveProps', this.props.children, this._entity);
-    }
-  }, {
-    key: 'componentWillUpdate',
-    value: function componentWillUpdate() {
-      debug(__com__, 'componentWillUpdate', this.props.children, this._entity);
-    }
-  }, {
     key: 'componentDidUpdate',
     value: function componentDidUpdate(prevProps) {
       debug(__com__, 'componentDidUpdate', this.props.children, this._entity);

+ 46 - 1
lib/api.js

@@ -14,7 +14,7 @@ export var loadApi = function loadApi() {
 
   return new APILoader({
     key: key,
-    useAMapUI: false,
+    useAMapUI: true,
     version: '1.4.7',
     protocol: 'https'
   }).load();
@@ -566,4 +566,49 @@ export var updatePolyline = function updatePolyline(entity, newOptions, newEvent
   };
 
   return commonUpdate(entity, newOptions, newEvents, oldOptions, oldEvents, operators, 'updatePolyline');
+};
+
+////////////////////////////////////////////////////////////
+// InfoWindow
+////////////////////////////////////////////////////////////
+/**
+ *
+ * @param {*} AMap
+ * @param {*} map
+ * @param {*} options 如果有dom用来显示,则其中的content字段即被填充为dom,不再用独立参数表示dom
+ * @param {*} events
+ */
+export var createInfoWindow = function createInfoWindow(AMap, options, events) {
+  var __func__ = 'createInfoWindow';
+  if (!AMap || !options || !options.map) {
+    console.log(__func__, 'fail! parameters!', 'AMap:' + !!AMap, 'options:' + !!options, 'options.map:' + !!(options && options.map));
+    return null;
+  }
+  var entity = new AMap.InfoWindow(options);
+  forOwn(events, function (value, key) {
+    entity.on(key, value);
+  });
+  console.log(__func__, 'ok!');
+  return entity;
+};
+
+export var updateInfoWindow = function updateInfoWindow(entity, newOptions, newEvents, oldOptions, oldEvents) {
+  var operators = {
+    isCustom: null,
+    autoMove: null,
+    closeWhenClickMap: null,
+    content: function content(v) {
+      return entity.setContent(v);
+    },
+    size: function size(v) {
+      return entity.setSize(v);
+    },
+    offset: null,
+    position: function position(v) {
+      return entity.setPosition(v);
+    },
+    showShadow: null
+  };
+
+  return commonUpdate(entity, newOptions, newEvents, oldOptions, oldEvents, operators, 'updateInfoWindow');
 };

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "react-amap-next",
-  "version": "1.1.4",
+  "version": "1.1.5",
   "description": "这是高德地图的react版本,相比react-amap更加简单,更加贴合react用户",
   "keywords": [
     "react",

+ 67 - 1
src/App.js

@@ -9,6 +9,7 @@ import Marker from './lib/Marker';
 import MassMarks from './lib/MassMarks';
 import Polygon from './lib/Polygon';
 import Polyline from './lib/Polyline';
+import InfoWindow from './lib/InfoWindow';
 
 class MarkerTest extends Component {
   constructor() {
@@ -384,6 +385,67 @@ class PolygonTest extends Component {
   }
 }
 
+class InfoWindowTest extends Component {
+  constructor() {
+    super();
+    this.state = {};
+    this._closeInfoWindow = this._closeInfoWindow.bind(this);
+  }
+
+  componentDidMount() {
+    loadMap('0325e3d6d69cd56de4980b4f28906fd8').then(AMap => {
+      let roadNet = new AMap.TileLayer.RoadNet();
+      let center = new AMap.LngLat(116.403322, 39.920255)
+      this.setState({ AMap, layers: [roadNet], center });
+    });
+  }
+  _closeInfoWindow(evt) {
+    console.log ('close infowindow!');
+    this.setState({isOpen:false})
+  }
+
+  render() {
+    const html = `<div><h4>Greetings</h4><p>This is content of this info window</p><p>Click 'Change Value' Button:</p></div>`;
+    const size = {
+      width: 250 + Math.random() * 20,
+      height: 140 + Math.random() * 20,
+    }
+    const offset = [Math.random() * 10, Math.random() * 10]
+
+    return (
+      <div>
+      <div>
+        <div style={{margin:2}}>
+          <input type='button' onClick={() => this.setState({ isOpen:true })} value='显示' />
+          <input type='button' onClick={() => this.setState({ isOpen:false })} value='隐藏' />
+        </div>
+        <Map
+          AMap={this.state.AMap}
+          style={{ width: 1100, height: 800 }}
+          options={{ center: this.state.center, layers: this.state.layers }}
+      >
+      {this.state.isOpen && (
+          <InfoWindow
+            AMap={this.state.AMap}
+            options={{
+              position: this.state.center,
+              isCustom:false,
+              content:html,
+              size,
+              offset
+              }}
+            events={{
+              close: this._closeInfoWindow
+            }}
+          />
+          )}
+        </Map>
+      </div>
+      </div>
+    );
+  }
+}
+
 class App extends Component {
   constructor() {
     super();
@@ -397,6 +459,7 @@ class App extends Component {
           <span style={{padding:5, margin: 5, backgroundColor:(this.state.test === 'marker')?'#ff0':'#fff'}} onClick={()=>this.setState({test: 'marker'})}> MarkerTest </span>
           <span style={{padding:5, margin: 5, backgroundColor:(this.state.test === 'massmarks')?'#ff0':'#fff'}} onClick={()=>this.setState({test: 'massmarks'})}> MassMarksTest </span>
           <span style={{padding:5, margin: 5, backgroundColor:(this.state.test === 'polygon')?'#ff0':'#fff'}} onClick={()=>this.setState({test: 'polygon'})}> PolygonTest </span>
+          <span style={{padding:5, margin: 5, backgroundColor:(this.state.test === 'infowindow')?'#ff0':'#fff'}} onClick={()=>this.setState({test: 'infowindow'})}> InfoWindowTest </span>
         </div>
         <div>
           {this.state.test === 'marker' &&
@@ -408,7 +471,10 @@ class App extends Component {
           {this.state.test === 'polygon' &&
           <PolygonTest />
           }
-          
+          {this.state.test === 'infowindow' &&
+          <InfoWindowTest />
+          }
+
         </div>
       </div>
     );

+ 85 - 0
src/lib/InfoWindow.js

@@ -0,0 +1,85 @@
+import React, { Component, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { createInfoWindow, updateInfoWindow } from './api';
+const __com__ = 'InfoWindow';
+//const debug = console.log;
+const debug = () => {};
+
+// https://lbs.amap.com/api/javascript-api/reference/infowindow
+export class InfoWindow extends Component {
+  static propTypes = {
+    AMap: PropTypes.object,
+    __map__: PropTypes.object,
+    options: PropTypes.object,
+    events: PropTypes.object
+  };
+
+  constructor() {
+    super();
+    this.refElement = null;
+    this._entity = null;
+    debug(__com__, 'constructor', this._entity);
+  }
+
+  componentDidMount() {
+    debug(__com__, 'componentDidMount', this._entity);
+    let { AMap, __map__, options, events, children } = this.props;
+    //let opts = { ...(options || {}), map: __map__, content: children };
+    let opts = { ...(options || {}), map: __map__ };
+    this._entity = createInfoWindow(AMap, opts, events);
+  }
+
+  componentDidUpdate(prevProps) {
+    debug(__com__, 'componentDidUpdate', this._entity);
+    let { AMap, __map__, options, events, children } = this.props;
+    //let opts = { ...(options || {}), map: __map__, content: children };
+    let opts = { ...(options || {}), map: __map__ };
+    if (!this._entity) {
+      this._entity = createInfoWindow(AMap, opts, events);
+      return;
+    }
+
+    // need check props changes, then update.
+    let oldOpts = {
+      ...(prevProps.options || {}),
+      map: prevProps.__map__
+    };
+    updateInfoWindow(this._entity, opts, events, oldOpts, prevProps.events);
+  }
+
+  componentWillUnmount() {
+    debug(__com__, 'componentWillUnmount', this._entity);
+    if (this._entity) {
+      //   this._entity.clearMap();
+      this._entity.setMap(null);
+      delete this._entity;
+      //   delete this._entity;
+      this._entity = null;
+    }
+  }
+
+  // shouldComponentUpdate(nextProps, nextState) {
+  //   debug(__com__, 'shouldComponentUpdate', this._entity);
+  //   return false;
+  // }
+  render() {
+    debug(__com__, 'render', this._entity);
+    let {
+      AMap,
+      options,
+      events,
+      match,
+      location,
+      history,
+      staticContext,
+      ...rest
+    } = this.props;
+    return null;
+    // return (
+    //   <React.Fragment>
+    //   </React.Fragment>
+    // )
+  }
+}
+
+export default InfoWindow;

+ 0 - 12
src/lib/Polygon.js

@@ -20,10 +20,6 @@ export class Polygon extends Component {
     debug(__com__, 'constructor', this._entity);
   }
 
-  componentWillMount() {
-    debug(__com__, 'componentWillMount', this._entity);
-  }
-
   componentDidMount() {
     debug(__com__, 'componentDidMount', this._entity);
     let { AMap, __map__, options, events, children } = this.props;
@@ -32,14 +28,6 @@ export class Polygon extends Component {
     this._entity = createPolygon(AMap, opts, events);
   }
 
-  componentWillReceiveProps(nextProps) {
-    debug(__com__, 'componentWillReceiveProps', this._entity);
-  }
-
-  componentWillUpdate() {
-    debug(__com__, 'componentWillUpdate', this._entity);
-  }
-
   componentDidUpdate(prevProps) {
     debug(__com__, 'componentDidUpdate', this._entity);
     let { AMap, __map__, options, events, children } = this.props;

+ 0 - 12
src/lib/Polyline.js

@@ -20,10 +20,6 @@ export class Polyline extends Component {
     debug(__com__, 'constructor', this._entity);
   }
 
-  componentWillMount() {
-    debug(__com__, 'componentWillMount', this.props.children, this._entity);
-  }
-
   componentDidMount() {
     debug(__com__, 'componentDidMount', this.props.children, this._entity);
     let { AMap, __map__, options, events, children } = this.props;
@@ -32,14 +28,6 @@ export class Polyline extends Component {
     this._entity = createPolyline(AMap, opts, events);
   }
 
-  componentWillReceiveProps(nextProps) {
-    debug(__com__, 'componentWillReceiveProps', this.props.children, this._entity);
-  }
-
-  componentWillUpdate() {
-    debug(__com__, 'componentWillUpdate', this.props.children, this._entity);
-  }
-
   componentDidUpdate(prevProps) {
     debug(__com__, 'componentDidUpdate', this.props.children, this._entity);
     let { AMap, __map__, options, events, children } = this.props;

+ 54 - 1
src/lib/api.js

@@ -8,7 +8,7 @@ import APILoader from './APILoader'
 export const loadApi = (key = '0325e3d6d69cd56de4980b4f28906fd8') => {
   return new APILoader({
     key,
-    useAMapUI: false,
+    useAMapUI: true,
     version: '1.4.7',
     protocol: 'https'
   }).load();
@@ -555,3 +555,56 @@ export const updatePolyline = (
   )
 };
 
+////////////////////////////////////////////////////////////
+// InfoWindow
+////////////////////////////////////////////////////////////
+/**
+ *
+ * @param {*} AMap
+ * @param {*} map
+ * @param {*} options 如果有dom用来显示,则其中的content字段即被填充为dom,不再用独立参数表示dom
+ * @param {*} events
+ */
+export const createInfoWindow = (AMap, options, events) => {
+  const __func__ = 'createInfoWindow';
+  if (!AMap || !options || !options.map) {
+    console.log(__func__, 'fail! parameters!', 'AMap:'+!!AMap, 'options:'+!!options, 'options.map:'+!!(options&&options.map));
+    return null;
+  }
+  let entity = new AMap.InfoWindow(options);
+  forOwn(events, (value, key) => {
+    entity.on(key, value);
+  });
+  console.log(__func__, 'ok!');
+  return entity;
+};
+
+export const updateInfoWindow = (
+  entity,
+  newOptions,
+  newEvents,
+  oldOptions,
+  oldEvents
+) => {
+  let operators = {
+    isCustom: null,
+    autoMove: null,
+    closeWhenClickMap: null,
+    content: v => entity.setContent(v),
+    size: v => entity.setSize(v),
+    offset: null,
+    position: v => entity.setPosition(v),
+    showShadow: null,
+  };
+
+  return commonUpdate (
+    entity,
+    newOptions,
+    newEvents,
+    oldOptions,
+    oldEvents,
+    operators,
+    'updateInfoWindow'
+  )
+};
+