我正在为我的项目使用谷歌地图反应库来显示企业的位置,单击标记我可以打开信息窗口,但是单击地图 div 之外的该标记的列表项时我无法打开信息窗口,因为我从上周开始就一直坚持这一点,并且无法在 google-maps-react 的文档中找到有用的东西。我的代码是
对于地图和列表
import React, { Component } from 'react'
import { Map, GoogleApiWrapper, Marker, InfoWindow } from 'google-maps-react';
import PlacesAutocomplete, { geocodeByAddress, getLatLng } from 'react-places-autocomplete';
import axios from 'axios'
import Header from '../components/header'
import Footer from '../components/footer'
import Features from '../components/features'
import Sponsors from '../components/sponsors'
import BannerAd from '../components/bannerAd'
import Spinner from '../components/spinner'
import { url } from '../../config'
import { BsChevronRight } from 'react-icons/bs'
class Places extends Component {
constructor(props) {
super(props)
this.state = {
address: '',
categoryId: 0,
categories: [],
places: [],
loading: false,
center: { lat: null, lng: null },
myLocation: { lat: 39.2820678, lng: -76.5916704 },
activeMarker: {},
showingInfoWindow: false,
selectedPlace: {},
range: 3,
}
}
componentDidMount() {
this.getCategories();
let address = ''
if (this.props.match.params.address !== 'undefined') {
address = this.props.match.params.address
}
this.setState({
address: address,
categoryId: this.props.match.params.category,
center: { lat: this.props.match.params.lat, lng: this.props.match.params.lng }
}, () => { this.getPlaces(); })
}
getCategories = async () => {
await this.setState({ loading: true })
axios.get(url + 'types').then((response) => {
this.setState({ categories: response.data, loading: false })
}).catch((error) => {
console.log(error)
})
}
getPlaces = async () => {
await this.setState({ loading: true })
axios.get(url + `places?lat=${this.state.center.lat}&lng=${this.state.center.lng}&typeId=${this.state.categoryId}&range=${this.state.range}`)
.then(async (response) => {
await this.setState({ places: response.data, loading: false })
})
.catch((err) => {
console.log(err)
})
}
handleChange = address => {
this.setState({ address });
};
handleSelect = async value => {
const address = await geocodeByAddress(value);
const center = await getLatLng(address[0]);
await this.setState({ center, address: value });
await this.getPlaces();
};
onChange = async (event) => {
await this.setState({ [event.target.name]: event.target.value });
await this.getPlaces()
}
onSelectPlace = async (place) => {
const center = { lat: place.location.lat, lng: place.location.lng }
const address = place.name;
await this.setState({ center, address, selectedPlace: place, });
}
onMarkerClick = (props, marker, e) => {
this.setState({
selectedPlace: props.place,
activeMarker: marker,
showingInfoWindow: true
});
}
centerMoved = (mapProps, map) => {
let lat = map.center.lat();
let lang = map.center.lng();
this.setState({ center: { lat: lat, lng: lang }, address: '' });
this.getPlaces();
}
onMapClicked = () => {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
}
handleZoomChanged = (mapProps, map) => {
let lat = map.center.lat();
let lang = map.center.lng();
{
map.zoom === 18 ? this.setState({ range: 1, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 17 ? this.setState({ range: 1, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 16 ? this.setState({ range: 1, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 15 ? this.setState({ range: 1.7, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 14 ? this.setState({ range: 2.697331, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 13 ? this.setState({ range: 8, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 12 ? this.setState({ range: 15, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 11 ? this.setState({ range: 22, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 10 ? this.setState({ range: 60, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 9 ? this.setState({ range: 100, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 8 ? this.setState({ range: 300, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 7 ? this.setState({ range: 750, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
: map.zoom === 6 ? this.setState({ range: 1000, center: { lat: lat, lng: lang } }) : this.setState({ range: 8, center: { lat: lat, lng: lang } }, () => { this.getPlaces() })
}
};
render() {
const myLocation = this.state.myLocation;
const center = this.state.center;
return (
<div>
<Header />
<div className='py-5 bg-danger'>
<div className='row'>
<div className='col-12'>
<div className='col-10 offset-1'>
<div className='card'>
<div className='card-body'>
<form className='form-row align-items-center justify-content-center'>
<div className='col-auto'>
<label className='h5'>Show me</label>
</div>
<div className='col-auto'>
<select id='categoryId' name='categoryId' className='custom-select ml-2' value={this.state.categoryId} onChange={this.onChange}>
<option value='0'>All</option>
{
this.state.categories && this.state.categories.map(category => {
return (
<option value={category.Id} key={category.Id}>{category.Name}</option>
)
})
}
</select>
</div>
<div className='col-auto'>
<label className='ml-4 h5'>Near</label>
</div>
<PlacesAutocomplete value={this.state.address} onChange={this.handleChange} onSelect={this.handleSelect}>
{
({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
<div className='search-input-container col-6'>
<input {...getInputProps({ placeholder: '210 S. Rolling Road, Catonsville, MD 21228', className: 'form-control ml-2' })} value={this.state.address} />
<div className='autocomplete-container'>
{
suggestions.map(suggestion => {
const className = suggestion.active ? 'suggestion-item suggestion-item--active' : 'suggestion-item';
return (
<div {...getSuggestionItemProps(suggestion, { className })}>
<span>{suggestion.description}</span>
</div>
);
})
}
</div>
</div>
)
}
</PlacesAutocomplete>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<div className='container-fluid vh-100 bg-white'>
<div className='row h-75'>
<div className='col-4 h-100 p-0 overflow-auto'>
<div className='card card-border shadow-lg'>
<div className='card-body'>
<Spinner display={this.state.loading}>
{this.state.places.length !== 0 ? <div className='list-group list-group-flush'>
{
this.state.places && this.state.places.map((place, index) => {
return (
<div className='list-group-item d-flex align-items-center' key={index} onClick={() => { this.onSelectPlace(place) }}>
<div className='mr-auto'>
<p className='font-weight-bold mb-0'>{place.name}</p>
<div className='small text-muted mb-0'>{place.description}</div>
<div className='small text-muted mb-0'><a className='text-dark font-weight-bold' href={`tel:${place.phone}`}>{place.phone}</a></div>
<div className='small text-muted mb-0'>Sun - Closed, M-F 9-5, Sat 12-5</div>
{place.CategoryId === 8 ? <div className='small text-muted mb-0'>Delivery, Carryout, Cubside</div> : ''}
<div className='small text-muted mb-1'><a href={place.website} target='_blank' >Website</a></div>
</div>
<BsChevronRight />
</div>
)
})
}
</div> : <div className='text-center'>No Business Found Nearby.<span><br></br>Please search a different location</span></div>}
</Spinner>
</div>
</div>
</div>
<div className='col-8 h-100 p-0'>
<Map google={this.props.google} minZoom={6} maxZoom={18} center={center} initialCenter={center} onDragend={this.centerMoved} onZoomChanged={this.handleZoomChanged} onClick={this.onMapClicked}>
{
this.state.places.map((place, index) => {
return <Marker className='labels'
key={index}
id={index} position={{ lat: place.location.lat, lng: place.location.lng }} onClick={this.onMarkerClick} place={place} />
})
}
<InfoWindow marker={this.state.activeMarker} visible={this.state.showingInfoWindow}>
<div>
<p className='font-weight-bold mb-1'>{this.state.selectedPlace && this.state.selectedPlace.name}</p>
<div className='text-muted mb-2'>{this.state.selectedPlace && this.state.selectedPlace.description}</div>
<div className='text-muted mb-0'>Sun - Closed, M-F 9-5, Sat 12-5</div>
{this.state.selectedPlace && this.state.selectedPlace.type_id === 8 ? <div className='text-muted mb-0'>Delivery, Carryout, Cubside</div> : ''}
</div>
</InfoWindow>
</Map>
</div>
</div>
</div>
<Features />
<Sponsors />
<BannerAd />
<Footer />
</div>
)
}
}
export default GoogleApiWrapper({ apiKey: 'myapikey' })(Places);
这里 onMarkerClick 打开标记上的信息窗口和函数 onSelectPlace 我想在地图中打开信息窗口它工作正常但在列表项中单击它不在这里输入图像描述