我正在努力寻找一种正确的方式来呈现自定义谷歌地图标记(覆盖)在一个反应-还原项目。我只有一页显示地图和搜索框。当有人搜索某个位置并找到该位置时,这将触发映射空闲事件,然后我将更新地图边界并搜索place信息,并将其保存在redux中。然后获取具有当前地图边界和城市名称的数据。当数据到达时,过滤列表(过滤将在将来转到后端,这意味着服务器将发送位于当前视图端口中的已过滤的列表),并呈现地图上每个列表的自定义覆盖。
在映射空闲事件上:
1)更新地图边界和搜索的地名
2)从服务器获取一些数据(json格式)。
3)过滤列表,这样我们只能呈现位置在当前视图中的列表(地图边界)。
4)为每个清单呈现自定义覆盖
在每个地图上出现的空闲事件(在地图上缩放或平移之后),上行、获取、过滤和呈现的整个过程都会重复进行。
到目前为止,我所做的是,该项目正在工作,直到反应需要确定哪些覆盖应该删除,哪一个应该重新绘制。
实际上,现在不能正常工作的是,当可见的列表数组更新时,React只是删除数组末尾的列表(从最后一个索引到0),而不是正确的列表(其位置不在视图端口)。
此外,有时,如果您已经搜索了一个地方,并玩了一些地图,并试图寻找另一个地方,新的地方覆盖是不正确的位置。相反,它们与地图视图相去甚远。
对于所有的Ract,Redux和Google技术,我都是比较新的,所以我意识到我可能在做一些非常愚蠢的事情。我希望这里的人能给我指明正确的方向。我搜遍了整个网,找不到合适的答案。我发现了一些有用的信息,关于如何创建自定义覆盖和如何创建反应组件的谷歌地图,我也知道有两个好的npm模块,可以完成我想要的工作(比如这个:react-google-maps和这个:google-map-react),但他们都有自己的问题,他们太复杂,我想要实现的。
很抱歉,这里粘贴了所有的代码,但我不知道如何在jsbin或类似的代码bin中表示整个项目环境。请让我知道,如果我需要做这样一个代码工作的例子,我会尝试。
这是我现在的密码。当然,这只是对问题很重要的部分:
映射组件
import React, { PropTypes, Component } from 'react';
import SearchBar from '../SearchBar';
import OverlayViewComponent from '../OverlayViewComponent';
import OverlayViewContent from '../OverlayViewContent';
import mapOptions from './cfg';
import MapStyles from './map.scss';
const propTypes = {
getListings: PropTypes.func.isRequired,
updateMapState: PropTypes.func.isRequired,
visibleListings: PropTypes.array.isRequired,
};
class GoogleMap extends Component {
constructor() {
super();
this._onMapIdle = this._onMapIdle.bind(this);
this.onPlacesSearch = this.onPlacesSearch.bind(this);
}
_initMap(mapContainer) {
// Create a new map
this._map = new google.maps.Map(mapContainer, mapOptions);
this._bindOnMapIdleEvent();
};
_bindOnMapIdleEvent() {
// Attach idle event listener to the map
this._map.addListener('idle', this._onMapIdle);
}
_onMapIdle() {
const { updateMapState, getListings } = this.props;
if (this._searchedPlace) {
console.log('ON MAP IDLE');
let mapBounds = this._map.getBounds().toJSON();
updateMapState(mapBounds, this._searchedPlace);
getListings();
}
};
onPlacesSearch(searchedPlace) {
if (searchedPlace.name !== '' && searchedPlace.geometry !== null) {
// Clear out the old marker if present.
if (this._searchedPlaceMarker) {
this._searchedPlaceMarker.setMap(null);
this._searchedPlaceMarker = null;
}
let bounds = new google.maps.LatLngBounds();
// Create a marker for the searched place.
this._searchedPlaceMarker = new google.maps.Marker({
map: this._map,
title: searchedPlace.name,
position: searchedPlace.geometry.location
});
if (searchedPlace.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(searchedPlace.geometry.viewport);
} else {
bounds.extend(searchedPlace.geometry.location);
}
// Save currently searchedPlace into the class local variable
this._searchedPlace = searchedPlace;
// Set map so it contains the searchedPlace marker (Ideally it should be only one)
this._map.fitBounds(bounds);
} else {
return;
}
}
componentDidMount() {
// When component is mounted, initialise the map
this._initMap(this._mapContainer);
};
shouldComponentUpdate(nextProps) {
if (nextProps.visibleListings.length == this.props.visibleListings.length) {
return false;
} else {
return true;
}
};
componentWillUnmount() {
google.maps.event.clearInstanceListeners(this._map);
};
render() {
console.log('GOOGLEMAP RENDER');
return (
<div id="mapContainer">
<div id="mapCanvas" ref={(mapContainer) => this._mapContainer = mapContainer}></div>
<SearchBar onPlacesSearch={this.onPlacesSearch} />
{
this.props.visibleListings.map((listing, index) => {
return (
<OverlayViewComponent key={index} mapInstance={this._map} position={listing.geo_tag}>
<OverlayViewContent listingData={listing} />
</OverlayViewComponent>
);
})
}
</div>
);
}
};
GoogleMap.propTypes = propTypes;
export default GoogleMap;OverlayView组件
import React, { PropTypes, Component } from 'react';
import OverlayView from './utils/overlayViewHelpers';
const propTypes = {
position: PropTypes.array.isRequired,
mapInstance: PropTypes.object.isRequired,
};
class OverlayViewComponent extends Component {
componentDidMount() {
this._overlayInstance = new OverlayView(this.props.children, this.props.position, this.props.mapInstance);
};
componentWillUnmount() {
this._overlayInstance.setMap(null);
};
render() {
return null;
}
};
OverlayViewComponent.propTypes = propTypes;
export default OverlayViewComponent;OverlayView类
import ReactDOM from 'react-dom';
const EL_WIDTH = 30;
const EL_HEIGHT = 35;
function OverlayView(element, position, map) {
this.overlayContent = element;
this.point = new google.maps.LatLng(position[0], position[1]);
this.setMap(map);
}
OverlayView.prototype = Object.create(new google.maps.OverlayView());
OverlayView.prototype.constructor = OverlayView;
OverlayView.prototype.onAdd = function() {
console.log('onAdd');
this.containerElement = document.createElement('div');
this.containerElement.style.position = 'absolute';
this.containerElement.style.width = EL_WIDTH + 'px';
this.containerElement.style.height = EL_HEIGHT + 'px';
let panes = this.getPanes();
panes.overlayMouseTarget.appendChild(this.containerElement);
ReactDOM.render(this.overlayContent, this.containerElement);
};
OverlayView.prototype.draw = function() {
console.log('draw');
if (this.containerElement) {
let projection = this.getProjection();
let projectedLatLng = projection.fromLatLngToDivPixel(this.point);
console.log(projectedLatLng);
this.containerElement.style.top = projectedLatLng.y - EL_HEIGHT + 'px';
this.containerElement.style.left = projectedLatLng.x - Math.floor(EL_WIDTH / 2) + 'px';
}
};
OverlayView.prototype.onRemove = function() {
console.log('onRemove');
let parentEl = this.containerElement.parentNode;
parentEl.removeChild(this.containerElement);
ReactDOM.unmountComponentAtNode(this.containerElement);
};
export default OverlayView;OverlayView内容组件
import React, { PropTypes } from 'react';
import markerIcon from '../../../images/icon-marker.png';
const propTypes = {
listingData: PropTypes.object.isRequired,
};
const OverlayViewContent = (listingData) => {
console.log('OverlayViewContent render');
return (
<div className="customIcon">
<img src={markerIcon} title={listingData.where} />
</div>
);
};
OverlayViewContent.propTypes = propTypes;
export default OverlayViewContent;发布于 2016-11-09 07:57:09
发布于 2016-11-03 14:21:04
尽管这个应用程序使用了这,但GMaps可能会对您有所帮助。
https://stackoverflow.com/questions/40403634
复制相似问题